GmSSL icon indicating copy to clipboard operation
GmSSL copied to clipboard

SM2加密密文格式问题

Open voyager11 opened this issue 2 years ago • 8 comments

这个密文格式或者编码是什么?怎么解?为什么加密出来的密文大多是以30开头,,加密出来的密文用其他软加密包解不开。这个有什么解法吗?

voyager11 avatar Nov 18 '22 08:11 voyager11

@voyager11

30是新的规范

open-shuaijun avatar Nov 18 '22 14:11 open-shuaijun

@voyager11

30是新的规范

那这个有办法解吗?用BC库。或者有办法转成旧规范 或者BC库有办法把密文转成新规范?就是想让它们能互认。很奇怪,只有这个加密出来的都是这个规范,阿里 京东 微信提供的加密包等等我们都用过,都不是这个,都是用BC库能解开的

voyager11 avatar Nov 19 '22 00:11 voyager11

@voyager11 其中一种方案是去兼容BC库,这里给出加密的转换过程,解密与其类似

BC库的非加密输出格式是 04+X+Y+HASH+ciphertext

  • 04表示0x04,1字节
  • X 去取SM2_CIPHERTEXT里面point.x
  • Y 去取SM2_CIPHERTEXT里面point.y
  • HASH 去取SM2_CIPHERTEXT里面hash
  • ciphertext 取密文

主要代码可以参见:

sm2_do_encrypt(&sm2Key, buf, buf_len, &C);
size_t out_len = 32 * 3 + int(C.ciphertext_size) + 1;
uint8_t c1c3c2[out_len];
c1c3c2[0] = 0x04;  // for bc_lib
memcpy(c1c3c2 + 1, C.point.x, 32);
memcpy(c1c3c2 + 1 + 32, C.point.y, 32);
memcpy(c1c3c2 + 1 + 32 + 32, C.hash, 32);
memcpy(c1c3c2 + 1 + 32 + 32 + 32, C.ciphertext, C.ciphertext_size);

最终c1c3c2就可以被BC库解密

open-shuaijun avatar Nov 19 '22 08:11 open-shuaijun

@596030631 感谢,我大概知道了,就是der编码解密的问题。应该可以解决了,周一去试试

voyager11 avatar Nov 19 '22 15:11 voyager11

请问使用SM2给数据长度大于255的数据加密怎么实现?

jiangyawei avatar Mar 22 '23 08:03 jiangyawei

请问博主将密文转换为ASN.1格式的了吗,分享一下吗

LiuxyData avatar Mar 24 '23 06:03 LiuxyData

@voyager11 其中一种方案是去兼容BC库,这里给出加密的转换过程,解密与其类似

BC库的非加密输出格式是 04+X+Y+HASH+ciphertext

  • 04表示0x04,1字节
  • X 去取SM2_CIPHERTEXT里面point.x
  • Y 去取SM2_CIPHERTEXT里面point.y
  • HASH 去取SM2_CIPHERTEXT里面hash
  • ciphertext 取密文

主要代码可以参见:

sm2_do_encrypt(&sm2Key, buf, buf_len, &C);
size_t out_len = 32 * 3 + int(C.ciphertext_size) + 1;
uint8_t c1c3c2[out_len];
c1c3c2[0] = 0x04;  // for bc_lib
memcpy(c1c3c2 + 1, C.point.x, 32);
memcpy(c1c3c2 + 1 + 32, C.point.y, 32);
memcpy(c1c3c2 + 1 + 32 + 32, C.hash, 32);
memcpy(c1c3c2 + 1 + 32 + 32 + 32, C.ciphertext, C.ciphertext_size);

最终c1c3c2就可以被BC库解密

有做过OpenSSL的兼容?

xiexuetao avatar Oct 25 '23 01:10 xiexuetao

@voyager11 其中一种方案是去兼容BC库,这里给出加密的转换过程,解密与其类似

BC库的非加密输出格式是 04+X+Y+HASH+ciphertext

  • 04表示0x04,1字节
  • X 去取SM2_CIPHERTEXT里面point.x
  • Y 去取SM2_CIPHERTEXT里面point.y
  • HASH 去取SM2_CIPHERTEXT里面hash
  • ciphertext 取密文

主要代码可以参见:

sm2_do_encrypt(&sm2Key, buf, buf_len, &C);
size_t out_len = 32 * 3 + int(C.ciphertext_size) + 1;
uint8_t c1c3c2[out_len];
c1c3c2[0] = 0x04;  // for bc_lib
memcpy(c1c3c2 + 1, C.point.x, 32);
memcpy(c1c3c2 + 1 + 32, C.point.y, 32);
memcpy(c1c3c2 + 1 + 32 + 32, C.hash, 32);
memcpy(c1c3c2 + 1 + 32 + 32 + 32, C.ciphertext, C.ciphertext_size);

最终c1c3c2就可以被BC库解密

方法可行,补充一下Qt下的实现:

const char* str = "12345678"; QByteArray ba(str, strlen(str));

SM2_CIPHERTEXT ctxt; sm2_do_encrypt(&sm2_key, reinterpret_cast<uint8_t *>(ba.data()), ba.size(), &ctxt);

QByteArray c1c3c2; c1c3c2.append(static_cast(0x04)); // 添加 0x04开头 QByteArray x(reinterpret_cast<const char*>(ctxt.point.x), 32); // SM2_POINT.x[32]; QByteArray y(reinterpret_cast<const char*>(ctxt.point.y), 32); // SM2_POINT.y[32]; QByteArray hash(reinterpret_cast<const char*>(ctxt.hash), 32); // SM2_CIPHERTEXT.hash[32] QByteArray cipherText1(reinterpret_cast<const char*>(ctxt.ciphertext), ctxt.ciphertext_size);

c1c3c2.append(x); c1c3c2.append(y); c1c3c2.append(hash); c1c3c2.append(cipherText1); QString hexStr2 = QString::fromUtf8(c1c3c2.toHex()); qDebug() << "ciphertext c1c3c2 :" << hexStr2;

使用网站验证ok: https://the-x.cn/zh-cn/cryptography/Sm2.aspx

StephenHu09 avatar Apr 30 '24 09:04 StephenHu09