当前位置:   article > 正文

基于OpenSSL,实现SM2密文数据的ASN1编码转换_sm2密钥转asn

sm2密钥转asn

基于OpenSSL, 实现算法的 Engine专栏

本专栏订阅后可查看以下文章

1、基于OpenSSL,实现RSA使用的hash的ASN1编码转换

2、基于OpenSSL,实现RSA公私钥的ASN1编码转换

3、实现SM2公私钥的格式转换

4、基于OpenSSL,实现SM2签名数据的ASN1编码转换

5、基于OpenSSL,实现SM2密文数据的ASN1编码转换

在实际应用场景中会遇到ASN1数据的编码转换,如,在硬件密码库中使用的API接口和在OpenSSL中使用的接口,很有可能是两种格式数据的表现形式,因此,本文提供以下方式进行数据格式的转换。

由于SM2密文格式分为C1C3C2和C1C2C3两种格式,所以在OpenSSL中并没有提供定义的ASN1编码结构和相关函数的定义,因为,需要用户自己定义ASN1编码的结构体。具体如下:

ASN1在线编码转换工具

  1. /****************************************************************
  2. * FileName: SM2_cipher.c
  3. * Author: labixiaoxin1849
  4. * Date: 2022-08-27
  5. * Description: call of OpenSSL,RSA key format conversion
  6. ****************************************************************/
  7. #include <string.h>
  8. #include <openssl/ec.h>
  9. #include <openssl/asn1.h>
  10. #include <openssl/asn1t.h>
  11. // 自定义ASN1编码结构
  12. typedef struct SM2_Ciphertext_st SM2_Ciphertext;
  13. DECLARE_ASN1_FUNCTIONS(SM2_Ciphertext)
  14. struct SM2_Ciphertext_st {
  15. BIGNUM *C1x;
  16. BIGNUM *C1y;
  17. ASN1_OCTET_STRING *C3;
  18. ASN1_OCTET_STRING *C2;
  19. };
  20. // SM2密文转ASN1编码(ASN1编码格式由上述SM2_Ciphertext_st定义)
  21. // cipher_x[in] : 密文C1的x分量,长度为32,不是公钥的x坐标
  22. // cipher_y[in] : 密文C1的y分量,长度为32,不是公钥的y坐标
  23. // cipher_m[in] : 密文C3,长度为32,原文的哈希值
  24. // cipher_c[in] : 密文C2
  25. // cipher_l[in] : 密文C2的长度
  26. // pbDer[out] : ASN1编码的SM2密文
  27. // uiDerLen[out] : ASN1编码的SM2密文长度
  28. int SM2_Cipher_Struct_to_Der(unsigned char *cipher_x, unsigned char *cipher_y, unsigned char *cipher_m, unsigned char *cipher_c, unsigned int cipher_l, unsigned char *pbDer, unsigned int *uiDerLen)
  29. {
  30. SM2_Ciphertext *xcipher;
  31. BIGNUM *x, *y;
  32. int ret = 1;
  33. do {
  34. x = y = NULL;
  35. xcipher = SM2_Ciphertext_new();
  36. x = BN_bin2bn(cipher_x, 32, NULL);
  37. y = BN_bin2bn(cipher_y, 32, NULL);
  38. if (!xcipher || !x || !y) {
  39. break;
  40. }
  41. if (xcipher->C1x) {
  42. BN_free(xcipher->C1x);
  43. }
  44. xcipher->C1x = x;
  45. if (xcipher->C1y) {
  46. BN_free(xcipher->C1y);
  47. }
  48. xcipher->C1y = y;
  49. x = y = NULL;
  50. if (!ASN1_OCTET_STRING_set(xcipher->C3, cipher_m, 32)) {
  51. break;
  52. }
  53. if (!ASN1_OCTET_STRING_set(xcipher->C2, cipher_c, cipher_l)) {
  54. break;
  55. }
  56. if (pbDer) {
  57. *uiDerLen = i2d_SM2_Ciphertext(xcipher, &pbDer);
  58. }
  59. else {
  60. *uiDerLen = i2d_SM2_Ciphertext(xcipher, NULL);
  61. }
  62. if ((int)*uiDerLen < 1) {
  63. break;
  64. }
  65. ret = 0;
  66. } while (0);
  67. if (xcipher) {
  68. SM2_Ciphertext_free(xcipher);
  69. }
  70. if (x) {
  71. BN_free(y);
  72. }
  73. if (x) {
  74. BN_free(y);
  75. }
  76. return ret;
  77. }
  78. // SM2密文ASN1编码转结构(ASN1编码格式由上述SM2_Ciphertext_st定义)
  79. // pbDer[in] : ASN1编码的SM2密文
  80. // uiDerLen[in] : ASN1编码的SM2密文长度
  81. // cipher_x[out] : 密文C1的x分量,长度为32,不是公钥的x坐标
  82. // cipher_y[out] : 密文C1的y分量,长度为32,不是公钥的y坐标
  83. // cipher_m[out] : 密文C3,长度为32,原文的哈希值
  84. // cipher_c[out] : 密文C2
  85. // cipher_l[out] : 密文C2的长度
  86. int SM2_Cipher_Der_to_Struct(const unsigned char *pbDer, unsigned int uiDerLen, unsigned char *cipher_x, unsigned char *cipher_y, unsigned char *cipher_m, unsigned char *cipher_c, unsigned int *cipher_l)
  87. {
  88. unsigned char pbTmp[8192] = { 0 };
  89. const unsigned char *data;
  90. int len;
  91. SM2_Ciphertext *xcipher;
  92. int ret = 1;
  93. do {
  94. xcipher = d2i_SM2_Ciphertext(NULL, &pbDer, uiDerLen);
  95. if (!xcipher) {
  96. break;
  97. }
  98. len = BN_bn2bin(xcipher->C1x, pbTmp);
  99. if (len > 32) {
  100. break;
  101. }
  102. memcpy(cipher_x, pbTmp, len);
  103. memset(pbTmp, 0, sizeof(pbTmp));
  104. len = BN_bn2bin(xcipher->C1y, pbTmp);
  105. if (len > 32) {
  106. break;
  107. }
  108. memcpy(cipher_y, pbTmp, len);
  109. len = ASN1_STRING_length(xcipher->C3);
  110. if (len > 32) {
  111. break;
  112. }
  113. data = ASN1_STRING_get0_data(xcipher->C3);
  114. if (!data) {
  115. break;
  116. }
  117. memcpy(cipher_m, data, len);
  118. *cipher_l = ASN1_STRING_length(xcipher->C2);
  119. if (*cipher_l > 512) {
  120. break;
  121. }
  122. data = ASN1_STRING_get0_data(xcipher->C2);
  123. if (!data) {
  124. break;
  125. }
  126. memcpy(cipher_c, data, *cipher_l);
  127. ret = 0;
  128. } while (0);
  129. SM2_Ciphertext_free(xcipher);
  130. return ret;
  131. }
  132. ASN1_SEQUENCE(SM2_Ciphertext) = {
  133. ASN1_SIMPLE(SM2_Ciphertext, C1x, BIGNUM),
  134. ASN1_SIMPLE(SM2_Ciphertext, C1y, BIGNUM),
  135. ASN1_SIMPLE(SM2_Ciphertext, C3, ASN1_OCTET_STRING),
  136. ASN1_SIMPLE(SM2_Ciphertext, C2, ASN1_OCTET_STRING),
  137. } ASN1_SEQUENCE_END(SM2_Ciphertext)
  138. // 由OpenSSL提供的宏,实现自定义的ASN1编码
  139. // 调用此宏,便定义了函数: SM2_Ciphertext_new、SM2_Ciphertext_free、d2i_SM2_Ciphertext、i2d_SM2_Ciphertext
  140. IMPLEMENT_ASN1_FUNCTIONS(SM2_Ciphertext)
  141. int main(int argc, char *argv[]){
  142. unsigned char c1x[] = {
  143. 0x57, 0xE9, 0x62, 0x22, 0xAB, 0x0A, 0x75, 0x43, 0x81, 0xA8, 0x43, 0x6A, 0xD9, 0x5F, 0xCC, 0xDD,
  144. 0x6B, 0x0D, 0xD4, 0xF6, 0x24, 0x1D, 0x13, 0xA0, 0x80, 0x2D, 0xE5, 0xD7, 0x09, 0x82, 0xF0, 0xF0
  145. };
  146. unsigned char c1y[] = {
  147. 0x97, 0xD3, 0x79, 0x5C, 0x79, 0x50, 0xF2, 0x78, 0x63, 0x50, 0x03, 0xA7, 0x08, 0xD5, 0x6C, 0x4F,
  148. 0xCB, 0x42, 0x44, 0xE4, 0xE2, 0x8C, 0xAA, 0x4F, 0x74, 0x4E, 0xF9, 0xE7, 0xA6, 0x82, 0x62, 0xE4
  149. };
  150. unsigned char c3[] = {
  151. 0xE7, 0x1B, 0x12, 0x51, 0x61, 0x40, 0xD3, 0xAC, 0x0C, 0x74, 0x84, 0x91, 0xBF, 0xE3, 0xEC, 0x0E,
  152. 0x60, 0x58, 0x24, 0xAA, 0xD5, 0x66, 0xC4, 0x48, 0x84, 0x10, 0xF4, 0x3C, 0x69, 0x29, 0xD0, 0x6C
  153. };
  154. unsigned char c2[] = {
  155. 0xB5, 0x92, 0xBF, 0x02, 0xD0, 0x53, 0xC2, 0x1A, 0x8A, 0x4A, 0xF1, 0x56, 0x21, 0x2E, 0xBD, 0x37
  156. };
  157. unsigned char der[256] = {0};
  158. unsigned int derlen = 0;
  159. unsigned char c1x2[32] = {0};
  160. unsigned char c1y2[32] = {0};
  161. unsigned char c32[32] = {0};
  162. unsigned char c22[32] = {0};
  163. unsigned int c22len = 0;
  164. // der 设置为NULL可以获得结构长度
  165. int rv = SM2_Cipher_Struct_to_Der(c1x, c1y, c3, c2, sizeof(c2), der, &derlen);
  166. if (rv != 0){
  167. return rv;
  168. }
  169. rv = SM2_Cipher_Der_to_Struct(der, derlen, c1x2, c1y2, c32, c22, &c22len);
  170. if (rv != 0){
  171. return rv;
  172. }
  173. if(memcmp(c1x, c1x2, 32) != 0 || memcmp(c1y, c1y2, 32) != 0 || memcmp(c3, c32, 32) != 0 ||
  174. sizeof(c2) != c22len || memcmp(c2, c22, c22len) != 0) {
  175. return -1;
  176. }
  177. printf("SM2 cipher exchange success!!!\n");
  178. return 0;
  179. }

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

闽ICP备14008679号