当前位置:   article > 正文

ECC加密——C++/OPENssl实现_c++ openssl openssl 3.0 ecc协商密钥

c++ openssl openssl 3.0 ecc协商密钥

一、介绍:

因为最近设计一些密钥交换相关的协议,做了很多调研,和学习。本来想直接使用ECC完成密钥交换协议,但是现存的很多代码都是基于ECDH的,这完全不是基于ECC加密的。尝试了很久之后终于自己手写了一份加密方案出来,为了方便更好的加解密,我封装成数组进行了,可自行更改。属实不易,全网独一份,希望大家点个赞,拷贝请声明。

二、代码:

请容我简单介绍一下思路:

其实在ECC相关开源库里可以看出并没有直接的加密解密。所以的咱们如何实现加密呢——点乘,m = a*G*c,a是私钥,c是明文,m是密文,a为私钥,G为基点,如果已知m、G,就无法破解获得c。如果解密只需要m乘a的逆。再说一些细节:

1:c是字符串,想要实现乘必须先将c转换成一种大数,再用大数点乘

2:a的逆如何求,我们要先获得椭圆曲线的阶n,a*x % n =1,x为a的逆。所以先获得阶n,再用大数库求逆。

3:为了更方便的输出,我将所有大数转成16进制输出,在很多场景中不需要解密,我们可以采用div参数设置输出16进制字符串的长度。

4:点赞、收藏,不然以后这么良心的作品要收费了!

 

ECDH.cpp

  1. void myECC::encrypt(std::string key, std::vector<std::string> &plaintext, std::vector<std::string> &strCipher_list, unsigned long long size, int div){
  2. BIGNUM *key_big = BN_new();
  3. char *hex_pk;
  4. BN_dec2bn(&key_big, (char *)key.data());//随机数转换成大数
  5. //建立椭圆曲线
  6. EC_KEY *ecdh = EC_KEY_new();
  7. EC_GROUP *group;
  8. EC_POINT *point_mul_aG, *point_mul_aGp;
  9. const EC_POINT *generator;
  10. ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);//NID_secp521r1
  11. group = (struct ec_group_st *) EC_KEY_get0_group(ecdh);
  12. point_mul_aG = EC_POINT_new(group);
  13. point_mul_aGp = EC_POINT_new(group);
  14. //获得基向量
  15. generator = EC_GROUP_get0_generator(group);
  16. //获得a*G
  17. EC_POINT_mul(group, point_mul_aG, NULL, generator, key_big, NULL);
  18. if(div) {
  19. for (int i = 0; i < size; ++i) {
  20. BN_dec2bn(&key_big, (char *) plaintext[i].data());
  21. EC_POINT_mul(group, point_mul_aGp, NULL, point_mul_aG, key_big, NULL);
  22. //hex_pk = EC_POINT_point2hex(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, NULL);
  23. EC_POINT_point2bn(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, key_big, NULL);
  24. hex_pk = BN_bn2dec(key_big);
  25. strCipher_list.push_back(((std::string) hex_pk).substr(0, div));
  26. }
  27. }else{
  28. for (int i = 0; i < size; ++i) {
  29. BN_dec2bn(&key_big, (char *) plaintext[i].data());
  30. EC_POINT_mul(group, point_mul_aGp, NULL, point_mul_aG, key_big, NULL);
  31. //hex_pk = EC_POINT_point2hex(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, NULL);
  32. EC_POINT_point2bn(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, key_big, NULL);
  33. hex_pk = BN_bn2dec(key_big);
  34. strCipher_list.push_back((std::string) hex_pk);
  35. }
  36. }
  37. EC_GROUP_free(group);
  38. EC_POINT_free(point_mul_aG);
  39. EC_POINT_free(point_mul_aGp);
  40. };
  41. void myECC::decrypt(std::string key, std::vector<std::string> &plaintext, std::vector<std::string> &strCipher_list, unsigned long long size, int div) {
  42. BIGNUM *key_big = BN_new();
  43. BIGNUM *data_big = BN_new();
  44. char *hex_pk;
  45. BN_dec2bn(&key_big, (char *) key.data());//随机数转换成大数
  46. //建立椭圆曲线
  47. EC_KEY *ecdh = EC_KEY_new();
  48. EC_GROUP *group;
  49. EC_POINT *point_mul_aG, *point_mul_aGp;
  50. ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);//NID_secp521r1
  51. group = (struct ec_group_st *) EC_KEY_get0_group(ecdh);
  52. point_mul_aG = EC_POINT_new(group);
  53. point_mul_aGp = EC_POINT_new(group);
  54. //获得阶N
  55. BIGNUM *order, *key_inverse;
  56. order = BN_new();
  57. key_inverse = BN_new();
  58. EC_GROUP_get_order(group, order,NULL);
  59. //求逆
  60. BN_mod_inverse( key_inverse,key_big, order,NULL);
  61. //EC_POINT_mul(group, point_mul_aG, NULL, generator, key_big, NULL);
  62. if(div){
  63. for (int i = 0; i < size; ++i) {
  64. char *str_a = (char *) strCipher_list[i].data();
  65. BN_dec2bn(&data_big, str_a);
  66. EC_POINT_bn2point(group, data_big, point_mul_aG, NULL);
  67. EC_POINT_mul(group, point_mul_aGp, NULL, point_mul_aG, key_inverse, NULL);
  68. //hex_pk = EC_POINT_point2hex(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, NULL);
  69. EC_POINT_point2bn(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, data_big, NULL);//将点转换成大数。
  70. hex_pk = BN_bn2dec(data_big);//将大数转换成整数字符串。
  71. plaintext.push_back(((std::string) hex_pk).substr(0, div));
  72. }
  73. } else{
  74. for (int i = 0; i < size; ++i) {
  75. char *str_a = (char *) strCipher_list[i].data();
  76. BN_dec2bn(&data_big, str_a);
  77. EC_POINT_bn2point(group, data_big, point_mul_aG, NULL);
  78. EC_POINT_mul(group, point_mul_aGp, NULL, point_mul_aG, key_inverse, NULL);
  79. //hex_pk = EC_POINT_point2hex(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, NULL);
  80. EC_POINT_point2bn(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, data_big, NULL);//将点转换成大数。
  81. hex_pk = BN_bn2dec(data_big);//将大数转换成整数字符串。
  82. plaintext.push_back((std::string) hex_pk);
  83. }
  84. }
  85. EC_GROUP_free(group);
  86. EC_POINT_free(point_mul_aG);
  87. EC_POINT_free(point_mul_aGp);
  88. }

ECDH.h

  1. //
  2. // Created by admin on 2022/10/9.
  3. //
  4. #ifndef BPIR_ECDH_H
  5. #define BPIR_ECDH_H
  6. #include <openssl/pem.h>
  7. #include <openssl/ecdh.h>
  8. #include <iostream>
  9. #include <sstream>
  10. #include <vector>
  11. namespace aes{}
  12. class myECC {
  13. public:
  14. void encrypt(std::string key, std::vector<std::string> &plaintext, std::vector<std::string> &strCipher_list, unsigned long long size, int div = 0);
  15. void decrypt(std::string key, std::vector<std::string> &plaintext, std::vector<std::string> &strCipher_list, unsigned long long size, int div = 0);
  16. };
  17. #endif //BPIR_ECDH_H

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/612186
推荐阅读
相关标签
  

闽ICP备14008679号