cryptography - 使用 openssl.exe 使用 256 位 RSA key 签名 20 字节消息,但不在代码中

标签 cryptography openssl rsa

我有一个 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/

相关文章:

php - 解析 X509 证书

macos - OpenSSL 无法使用 gem ruby​​gems 或 brew 或 bundle 加载库

java - JSch 在尝试通过 KeyPairGenerator 加载 RSA 私钥时获得 "invalid privatekey:"

ios - `SecKey` RSA 对象创建失败,错误域代码=-50“从数据创建 RSA 私钥失败 swift-iOS

c# - 使用 RSACryptoServiceProvider 签名的速度

java - Spring配置服务器安全加密和解密不起作用

python - 将 Fernet key 写入文本文件会生成字节字符串而不是 ASCII 字符串

python-3.x - Lenstras 椭圆曲线属性错误问题

c++ - 为支持 OpenSSL 的 Windows Phone 8.1 编译 Qt 5.5 的问题

java - 解密加密消息摘要时出现非法 block 大小异常