当前位置:   article > 正文

基于OpenSSL,实现SM2签名数据的ASN1编码转换_签名编码格式 asn

签名编码格式 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中使用的接口,很有可能是两种格式数据的表现形式,因此,本文提供以下方式进行数据格式的转换。

ASN1在线编码转换工具

  1. /****************************************************************
  2. * FileName: SM2_sig.c
  3. * Author: labixiaoxin1849
  4. * Date: 2022-08-27
  5. * Description: call of OpenSSL,SM2 key format conversion
  6. ****************************************************************/
  7. #include <string.h>
  8. #include <openssl/ec.h>
  9. // SM2算法,而非ECC
  10. // SM2签名数据结构转为ASN1编码
  11. // sig_r[in] : 签名的r部分
  12. // sig_s[in] : 签名的s部分
  13. // pbDer[out] : 转换后的ASN1编码数据
  14. // uiDerLen[out] : 转换后的ASN1编码数据长度
  15. int SM2_Signature_Struct_to_Der(const unsigned char *sig_r, const unsigned char *sig_s, unsigned char *pbDer, unsigned int *uiDerLen)
  16. {
  17. ECDSA_SIG *xsig;
  18. BIGNUM *r, *s;
  19. int ret = -1;
  20. do {
  21. r = s = NULL;
  22. xsig = ECDSA_SIG_new();
  23. r = BN_bin2bn(sig_r, 32, NULL);
  24. s = BN_bin2bn(sig_s, 32, NULL);
  25. if (!xsig || !r || !s) {
  26. break;
  27. }
  28. if (!ECDSA_SIG_set0(xsig, r, s)) {
  29. break;
  30. }
  31. r = s = NULL;
  32. if (pbDer) {
  33. *uiDerLen = i2d_ECDSA_SIG(xsig, &pbDer);
  34. } else {
  35. *uiDerLen = i2d_ECDSA_SIG(xsig, NULL);
  36. }
  37. if ((int)*uiDerLen < 1) {
  38. break;
  39. }
  40. ret = 0;
  41. } while (0);
  42. if (xsig) {
  43. ECDSA_SIG_free(xsig);
  44. }
  45. if (r) {
  46. BN_free(r);
  47. }
  48. if (s) {
  49. BN_free(s);
  50. }
  51. return ret;
  52. }
  53. // SM2签名数据的ASN1编码转结构
  54. // pbDer[in] : 转换后的ASN1编码数据
  55. // uiDerLen[in] : 转换后的ASN1编码数据长度
  56. // sig_r[out] : 签名的r部分
  57. // sig_s[out] : 签名的s部分
  58. int SM2_Signature_Der_to_Struct(const unsigned char *pbDer, unsigned int uiDerLen, unsigned char *sig_r, unsigned char *sig_s)
  59. {
  60. unsigned char pbTmp[64] = { 0 };
  61. int len;
  62. ECDSA_SIG *xsig;
  63. int ret = -1;
  64. do {
  65. xsig = d2i_ECDSA_SIG(NULL, &pbDer, uiDerLen);
  66. if (!xsig) {
  67. break;
  68. }
  69. memset(pbTmp, 0x00, sizeof(pbTmp));
  70. len = BN_bn2bin(ECDSA_SIG_get0_r(xsig), pbTmp);
  71. if (len > 32) {
  72. break;
  73. }
  74. memcpy(&sig_r[32 - len], pbTmp, len);
  75. memset(pbTmp, 0x00, sizeof(pbTmp));
  76. len = BN_bn2bin(ECDSA_SIG_get0_s(xsig), pbTmp);
  77. if (len > 32) {
  78. break;
  79. }
  80. memcpy(&sig_s[32 - len], pbTmp, len);
  81. ret = 0;
  82. } while (0);
  83. if (xsig) {
  84. ECDSA_SIG_free(xsig);
  85. }
  86. return ret;
  87. }
  88. int main(int argc, char *argv[]){
  89. unsigned char r[32] = {
  90. 0x37, 0x1B, 0xAE, 0xC3, 0xC2, 0x32, 0x20, 0xEC, 0xF7, 0x91, 0xE3, 0x6B, 0x47, 0x26, 0x04, 0x64,
  91. 0x5A, 0x69, 0xE1, 0x86, 0x9E, 0x6D, 0x51, 0xC9, 0x85, 0x4E, 0xA1, 0xDD, 0x07, 0xD3, 0x57, 0x9F
  92. };
  93. unsigned char s[32] = {
  94. 0xDF, 0xAE, 0xE5, 0x73, 0xE6, 0x3E, 0x9C, 0xB3, 0xA4, 0x64, 0xDA, 0xB2, 0xEA, 0x83, 0x4F, 0xEB,
  95. 0x00, 0xF5, 0xD2, 0x64, 0xE1, 0xD6, 0x3F, 0xF0, 0x70, 0x60, 0xC0, 0x61, 0xF4, 0xDE, 0x2E, 0x30
  96. };
  97. // 经过编码后的长度大于64
  98. unsigned char der[128] = {0};
  99. unsigned int derlen = 0;
  100. unsigned char r2[32] = {0};
  101. unsigned char s2[32] = {0};
  102. // der_out 设置为NULL可以获得结构长度
  103. int rv = SM2_Signature_Struct_to_Der(r, s, der, &derlen);
  104. if(rv != 0){
  105. return rv;
  106. }
  107. rv = SM2_Signature_Der_to_Struct(der, derlen, r2, s2);
  108. if(rv != 0){
  109. return rv;
  110. }
  111. if(memcmp(r, r2, 32) != 0 || memcmp(s, s2, 32) != 0) {
  112. return -1;
  113. }
  114. printf("SM2 signature exchange success!!!\n");
  115. return 0;
  116. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号