GmSSL
GmSSL copied to clipboard
SM2加密密文格式问题
这个密文格式或者编码是什么?怎么解?为什么加密出来的密文大多是以30开头,,加密出来的密文用其他软加密包解不开。这个有什么解法吗?
@voyager11
30是新的规范
@voyager11
30是新的规范
那这个有办法解吗?用BC库。或者有办法转成旧规范 或者BC库有办法把密文转成新规范?就是想让它们能互认。很奇怪,只有这个加密出来的都是这个规范,阿里 京东 微信提供的加密包等等我们都用过,都不是这个,都是用BC库能解开的
@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库解密
@596030631 感谢,我大概知道了,就是der编码解密的问题。应该可以解决了,周一去试试
请问使用SM2给数据长度大于255的数据加密怎么实现?
请问博主将密文转换为ASN.1格式的了吗,分享一下吗
@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的兼容?
@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
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