我有一个 256 位私钥,我想用它来签署 SHA-1 摘要(20 字节)。直接使用 openssl 似乎可以工作
echo doesntmatter | openssl dgst -sha1 -binary | openssl rsautl -sign -inkey 256bit_private_key.pem | openssl enc -base64
按预期给我一个 Base64 输出。
但是使用 OpenSSL 执行此操作失败并显示“错误:04075070:rsa 例程:RSA_sign:digest 对于 rsa key 而言太大”。如下所示,我将 20 字节 (SHA_DIGEST_LENGTH=20) SHA-1 摘要作为输入传递给 RSA_sign。即使有填充,它也不应该超过我可以用 256 位模数 key 加密的最大 32 字节?!
unsigned char digest[SHA_DIGEST_LENGTH];
SHA1(message, messageSize, digest);
unsigned int privateKeySize = RSA_size(privateKey); // 256 bits = 32 bytes
unsigned char* signature = new unsigned char[privateKeySize];
unsigned int signatureSize;
int res = RSA_sign(NID_sha1, digest, SHA_DIGEST_LENGTH, signature, &signatureSize, privateKey);
if(res == 0)
{
int err = ERR_get_error(); // 67588208
char *s = ERR_error_string(err, 0); // error:04075070:lib(4):func(117):reason(112)
delete [] signature;
[...]
}
我在代码中做错了什么?
最佳答案
看看这个SO answer . rsautl
已贬值,取而代之的是 pkeyutl
本质上,RSA 签名应该使用 RSA-PSS 签名填充方案以确保安全,并且 RSA-PSS 将严格大于摘要,因为需要传递盐。此外,RSA_sign
将摘要作为签名方案的一部分,因此您的代码将对摘要进行摘要。您想要直接传递消息,或者使用 RSA_private_encrypt
结合合适的 RSA_padding_add_x
调用。
正如我在评论中所说,256 位 key 对于对称算法来说足够安全,但破解 RSA 私钥(顺序为 4 minutes on a couple of year old machine )将是微不足道的。使用最少的 1024 位 key (可能还有 2048 或 4096 位 key )会给你一个 security level大致相当于一个 128 位的对称算法。
关于cryptography - 使用 openssl.exe 使用 256 位 RSA key 签名 20 字节消息,但不在代码中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15092298/