RSA 签名大小不匹配

RSA Signature Size Mismatch

如前所述here,消息签名的长度等于私钥的模数,又名 Public 密钥。

我正在实施一个对消息进行签名的系统,但我遇到了无法解决的大小不匹配问题。 我用 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 字节长吗?

是不是我用的算法有问题?

Shouldn't the MaxSignatureLength, and the RSA Signature length 420 bytes long ?

没有。您要求使用 3072 位或 384 字节的密钥。这是签名大小的限制。

每个密码系统在这方面可能会有所不同。

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

这是 {OID,n,e} 的大小加上 ASN.1 framing or overhead. See your previous question 的外观(特别是命令 dumpasn1 rsa-public.der 的输出)。

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

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

Is the problem with the algorithm I use ?

不,您通过调用 MaxSignatureLength() 正确地做事。


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

我只是猜测,但您似乎也有设计问题。

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

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


认为您应该做的是使用集成加密方案来回发送加密消息。为此,请参阅 Elliptic Curve Integrated Encryption Scheme (ECIES) and Discrete Logarithm Integrated Encryption Scheme (DLIES)。 ECIES 对椭圆曲线进行运算,DLIES 对整数进行运算。

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

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

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