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
MaxSignatureLength
和 RSA 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 作为密钥的一部分发送:)
如前所述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
MaxSignatureLength
和 RSA 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 作为密钥的一部分发送:)