RSA签名大小不匹配

RSA Signature Size Mismatch

本文关键字:不匹配 RSA      更新时间:2023-10-16

如本文所述,消息签名的长度等于私钥的模数,也就是公钥。

我正在实现一个签名消息的系统,并且我有一个无法解决的大小不匹配。我使用crypto++

下面是我使用的代码:
/* Create RSA Keys */
RSA::PrivateKey privateKey;
privateKey.GenerateRandomWithKeySize(prng, 3072);
RSA::PublicKey publicKey(privateKey);
cout << ">> RSA Keys generated";
    /* Key Size */
    string spki;
    StringSink sSink(spki);
    publicKey.Save(sSink);
    cout <<" ("<< spki.size()<<" bytes)"<<endl;
RSASSA_PKCS1v15_SHA_Signer signer(privateKey);
size_t length = signer.MaxSignatureLength();
cout <<"MaxSignatureLength " <<length<<endl;
    SecByteBlock signature( length );

输出为:

>> RSA Keys generated (420 bytes)
>> ServerHello sent (436 bytes)
   MaxSignatureLength 384
   RSA Signature length 384

MaxSignatureLengthRSA Signature length不应该长420字节吗?

是我使用的算法有问题吗?

MaxSignatureLength和RSA签名长度不应该是420字节吗?

。您正在请求3072位或384字节的密钥。这是签名大小的限制。

每个密码系统在这方面可能是不同的。

cout <<" ("<< spki.size()<<" bytes)"<<endl;

这是带有ASN.1帧或开销的{OID,n,e}的大小。请参阅前面的问题在数据包有效负载中发送PublicKey,以了解它的样子(特别是命令dumpasn1 rsa-public.der的输出)。

cout <<"MaxSignatureLength " <<length<<endl;

如果我没记错的话,这是RSA的n - 1

是我使用的算法有问题吗?

不,你通过调用MaxSignatureLength()做的事情是正确的。


 >> RSA Keys generated (420 bytes)
 >> ServerHello sent (436 bytes)

我只是猜测,看来你的设计也有问题。

当你加密一条消息时,比如ServerHello,你通常用对称密码加密,比如AES或Camellia。然后,使用对称密码密钥,并在RSA密钥下对其进行加密。最后,您将配对{encrypted symmetric cipher key, encrypted message under symmetric cipher}发送给另一方。

在上面部分描述的系统中,您只在公钥下加密16或32个字节。


认为你应该做的是使用集成加密方案来来回发送加密消息。具体请参见椭圆曲线综合加密方案(ECIES)和离散对数综合加密方案(DLIES)。ECIES操作在椭圆曲线上,DLIES操作在整数上。

集成加密方案具有一些非常理想的安全属性,例如IND-CCA2。他们通过而不是来实现它,允许您做一些事情,比如重用安全上下文,因此安全性被纳入方案。

但是,您仍然需要解决密钥分发问题。这是一个棘手的问题,我们没有一个好的、可扩展的解决方案。

现在你明白为什么算法敏捷性是重要的,以及为什么你希望OID作为密钥的一部分在握手阶段发送:)