【问题标题】:Why I got different signature when I perform RSA sign in C++ and Python?为什么我在 C++ 和 Python 中执行 RSA 签名时得到不同的签名?
【发布时间】:2017-05-11 02:56:53
【问题描述】:

我正在尝试使用 sha1 创建 RSA 签名。基本步骤是:

  1. 使用 sha1 对源数据进行哈希处理(以获取摘要)
  2. 使用摘要和私钥进行 RSA 签名
  3. 将签名转换为十六进制字符串

所以,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


【解决方案1】:

您提供的可能推断是函数 bintohex 正在切断签名,因为它遇到表示字符串终止的“00”('\0')。从您的 C++ 代码生成的 sig 已转换只到十六进制,直到没有遇到 \0。

您可以做的是,尝试从 python 和 c++ 代码为其他一些(测试)消息生成签名,以缩小问题范围并确保 bintohex 在这种情况下缩短签名,通过观察您是否得到相同其他消息正文上的签名,如果它们仍然不同,请查看 c++ 签名是否缩短为 00。

【讨论】:

  • 是的,没错。制作签名没有问题。真正的问题在于翻译字符串。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2012-11-05
  • 1970-01-01
  • 1970-01-01
  • 2012-01-16
  • 2021-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多