【发布时间】:2017-05-11 02:56:53
【问题描述】:
我正在尝试使用 sha1 创建 RSA 签名。基本步骤是:
- 使用 sha1 对源数据进行哈希处理(以获取摘要)
- 使用摘要和私钥进行 RSA 签名
- 将签名转换为十六进制字符串
所以,Python 代码是这样的:
pri_key = RSA.load_key(key_file);
digest = sha1_func(data).digest();
signature = pri_key.sign(digest, 'sha1')
;
return binascii.hexlify(signature);
源数据为:
s34caoguangshui@163.com1100
这是最终结果:
2034c9d2cacfdac1a69b737ab00d3fc42e8533b656f638c60ca503924706e49f017d2b29c8efe6903927c2b02fd24a5f50fef49ba137697983ece22761082b00ac433362b305023814e95278641ad8d8b3aa097f79bd392a325ee7182881b5e6a2d4e4d383c49a8842a3f6cdaee8deb33c257385aa2cf2946216cf09c6383145
我正在使用 OpenSSL 库在 C++ 中编程。我采取了与我认为相同的步骤,但得到了不同的结果。实际上我只得到了上面发布的结果的前半部分:
2034c9d2cacfdac1a69b737ab00d3fc42e8533b656f638c60ca503924706e49f017d2b29c8efe6903927c2b02fd24a5f50fef49ba137697983ece22761082b
后半段去哪了?
这是我的 C++ 代码:
int rc = 1;
SHA_CTX sha_ctx = { 0 };
unsigned char digest[SHA_DIGEST_LENGTH];
rc = SHA1_Init(&sha_ctx);
if (1 != rc) { }
rc = SHA1_Update(&sha_ctx, source_data, source_len);
if (1 != rc) { }
rc = SHA1_Final(digest, &sha_ctx);
if (1 != rc) { }
RSA* rsa = PEM_read_RSAPrivateKey(private_key_file, NULL, NULL, NULL);
int sig_len = 0;
unsigned char* sig = malloc(RSA_size(rsa));
rc = RSA_sign(NID_sha1, digest, sizeof digest, sig, &sig_len, rsa);
if (1 != rc) { }
return binToHex(sig);
此外,我从第一步中得到了相同的摘要。 我还尝试了更推荐的 EVP API:
EVP_PKEY* private_key = PEM_read_PrivateKey(private_key_file, NULL, NULL, NULL);
EVP_MD_CTX evp_ctx;
EVP_SignInit(&evp_ctx, EVP_sha1());
EVP_SignUpdate(&evp_ctx, source_data, source_len);
EVP_SignFinal(&evp_ctx, sig, sig_len, private_key);
return binToHex(sig);
我也只拿到了前半部分。
【问题讨论】:
-
您可能没有为字符串分配足够的空间。
-
binToHex 可能是罪魁祸首。短 sig 在零字节处被截断; C 使用
\0作为字符串终止符。 -
buff 信号足够大。 @PM2Ring 是对的。非常感谢你们。
-
您想为这个问题使用哪个副本:different signature RSA site:stackoverflow.com。对于 OpenSSL 签名,请参阅 wiki 上的 EVP Signing and Verifying。对于 OpenSSL 和 C++,请参阅 OpenSSL wiki 上的 C++ Programs。
标签: python c++ openssl rsa sign