做RSA的一种方法“;“加密”;使用命令行openssl创建填充SHA256哈希

做RSA的一种方法“;“加密”;使用命令行openssl创建填充SHA256哈希,openssl,rsa,encryption,bignum,Openssl,Rsa,Encryption,Bignum,我正试图提出一个使用openssl的单行程序解决方案,它将接收消息的填充SHA256摘要(本例中为256字节,对于RSA2048),并对256字节摘要应用RSA“解密”,即 m^d mod n 其中n是模数,d是专用指数,m是摘要消息(填充)。这是在正常的RSA2048身份验证中通常会发生的事情,但我需要零碎地进行 我试过了,但没用 openssl rsautl -decrypt -in msg.sha256 -inkey secret.pem -out msg.sha256.sig RSA

我正试图提出一个使用openssl的单行程序解决方案,它将接收消息的填充SHA256摘要(本例中为256字节,对于RSA2048),并对256字节摘要应用RSA“解密”,即

m^d mod n
其中n是模数,d是专用指数,m是摘要消息(填充)。这是在正常的RSA2048身份验证中通常会发生的事情,但我需要零碎地进行

我试过了,但没用

openssl rsautl -decrypt -in msg.sha256 -inkey secret.pem -out msg.sha256.sig
RSA operation error
2675740:error:04065084:rsa routines:RSA_EAY_PRIVATE_DECRYPT:data too large for
modulus:rsa_eay.c:532:
希望我混淆了加密和解密(因为我想在计算中使用私有指数),我也尝试了这个

openssl rsautl -encrypt -in msg.sha256 -inkey secret.pem -out msg.sha256.sig
RSA operation error
2675740:error:0406D06E:rsa routines:RSA_padding_add_PKCS1_type_2:data too large
for key size:rsa_pk1.c:151:
阅读RSA“加密/解密”,在本例中,我认为我混淆了文件加密/解密和单消息加密/解密。文件加密显然是一个更高级别的协议,涉及AES128和所有这些。我不想这样,我只想用私有指数进行模幂运算

我还尝试了
pkeyutil
(据我所知,这是具有相同结果的首选方法)。我很确定我走错了路,也许这在命令行中是不可能的(我知道在使用“bignum”的C API中是可行的)

---更新----

我尝试从SHA256散列中删除PKCS1 v1.5填充(因此我只剩下32个字节的散列),并将其传递出去,但也没有成功

$ head -32c msg.sha256 | openssl.exe rsautl -decrypt -inkey secret.pem -out test.sig
RSA operation error
2675740:error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is
 not 02:rsa_pk1.c:190:
2675740:error:04065072:rsa routines:RSA_EAY_PRIVATE_DECRYPT:padding check failed
:rsa_eay.c:616:
我用
-raw
尝试了同样的方法,结果没有出现错误,但结果不是我所期望的(这是我所期望的,因为它没有PKCS1v1.5填充)。然后我尝试反转输入文件的字节顺序,因为openssl似乎在抱怨输入文件(作为256字节的BIGNUM)略大于模(作为256字节的BIGNUM),如果反转字节顺序,则尾随的0将变为前导的0,并且更小。它完成了,但结果仍然不正确

$ perl -e '$a = `cat msg.sha256`; print "".reverse($a);' > msg.sha256r

$ head -256c msg.sha256r | openssl.exe rsautl -encrypt -raw -inkey secret.pem -out test3e.sig
$ head -256c msg.sha256r | openssl.exe rsautl -decrypt -raw -inkey secret.pem -out test3d.sig
是的,我意识到我只是在黑暗中蹒跚而行,但你会惊讶我有多少次如此幸运


test3e.sig和test3d.sig都不同意我从第三方工具进行的计算。

也许可以尝试使用
-raw
参数。如果消息已填充到正确的大小,则不希望实用程序尝试填充它。默认情况下,它假定
-pkcs
(pkcs 1.5),这将解释为什么会出现“太大”错误。

您得到的错误,
数据对于模数太大
,是因为您输入了以下代码的第二个
if

/* make data into a big number */
if (BN_bin2bn(from,(int)flen,f) == NULL) goto err;

if (BN_ucmp(f, rsa->n) >= 0)
    {
    RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
    goto err;
    }
BN_bin2bn
将数据
(无符号字符*)转换为bignum
f
(bignum)。
然后比较bignums
f
和模数
n
<代码>>=0
表示
f>=n

由于您的输入是SHA256摘要(256字节,2048位),因此转换的摘要值可能大于2048位模数
n
,因此会发生错误

如果你能把你的信息改短一点,这似乎是可行的。另外,您调用的函数在计算
f^d mod n
后进行填充,如下所示

if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
            rsa->_method_mod_n))

您可能需要切换到RSA\u NO\u PADDING
模式以获得预期的答案。

-raw
给出了相同的结果(太大)。我尝试了,但没有成功。我只发送了32个字节,让它尝试用PKCS1v1.5填充,但它仍在抱怨。我真的应该让这个问题休息一下,但现在我很好奇,因为我是密码学的初学者。如果要求
f
,那么这是否由填充最高有效位(0x0001FFFF…向下至SHA256)的特定PKC选择来实现?如果openssl工具抱怨填充的2048位“太大”,那么它必须以big-endian而不是little-endian读取我的文件。但是我试过了,虽然它没有抱怨,但它给出了错误的答案。我不认为填充是得到错误答案的原因。正如big endian所说,解密函数正在读取您的文件。我试图得到你想要的结果,但答案不正确。我猜这是因为“rsa_致盲”被打开了;否则
if(!rsa->meth->rsa\u mod\u exp(ret,f,rsa,ctx))会出错应给出正确答案。你使用的工具对你的目的来说太强大了,导致我们陷入困境:P尝试GMP。