如何使用 crypto++ 库验证数字签名?
输入数据为:
- public_key BASE64 编码的十六进制字符串。
- 来自公钥的公共(public)指数。
- 十六进制字符串签名。
我不知道私钥部分。 我已经编写了这个测试函数,但它总是以“VerifierFilter:数字签名无效”错误结束。
这里的 key 是从有效的 key 对导出的!
void rawRSAVerificationTest()
{
// RSA 2048 digital signature verification
try {
std::string pupKeyStr ("e0c3851114c758fb943a30ca8f9b4c7f506d52aa101c34ad5134f2cdbdddbef11ee6d1470d54caf3774d4d17d69488abf0b78beaebc046115cb29617610e98be3d5c303e19c14ae57ce0994701e3f24a628abf5c421777fb3c2b9b8b17f2a4cda4b9fd89e3c122085831c3e4502734bc3f3157d3ccd01198a8e3795f03661b55112acb69e8d5782bdf506bf5222777baf382d4d4bc2dd83e53af9236ed6e7a0fb8b5bb543ed4abbf478911bdc517e13e580b138f10f153eb2733ad60f3796e99b7d59f9abbd6666c69ba5ecc17a391424dc8ca3cf24a759c62d490056cda30265e11e316e7695028721c50eaf8e596161f0b59e4f598c85063bb3a847a5acb9d");
//sha256 hashed data signature
std::string signatureStr = "d8d1df600d6781a9c030d9c697ec928eac34bf0670cf469f7fffb9c046deaee359b4e1218b419ff2589434510db8470ccf7abd28876a04b8d5a27293723e897f97a9367d2fbb379f8c52ec2a04cb71a06891a3f44d00e8bb9622b2038dbe6f29d0118203c372853ae09fb820702f1c16ee772998bd8a3db9e5127992a18d999fc422822caf0a82d9c12d6231605457ce651b0350b1e98584f9d4e6b973d6668df863d4b73784bbc00d8449918a0f049ddbeffc0d79579ade13a2d9012906b7ded7aae934bc54c5b85c924aee6627d66b7b200a23cd9b6a9c14650f1f9384e9ef9b90ac217ece026a1802bc0623150057ecd2b31f5f758e4ff866bb2e81d28368";
//Chinese Remainder Theorem (CRT)
std::string pupExpStr ("0x10001");
CryptoPP::AutoSeededRandomPool rng;
CryptoPP::RSA::PublicKey pubKeyRaw;
CryptoPP::Integer pup_key_cast( static_cast<CryptoPP::Integer> (pupKeyStr.c_str()));
CryptoPP::Integer pup_exp_cast( static_cast<CryptoPP::Integer> (pupExpStr.c_str()));
pubKeyRaw.Initialize(pup_key_cast, pup_exp_cast);
if (!pubKeyRaw.Validate(rng, 3))
{
std::cout << "Error while public key validation" << std::endl;
}
CryptoPP::RSASS<CryptoPP::PSS, CryptoPP::SHA256>::Verifier verifier_sha256(pubKeyRaw);
CryptoPP::StringSource( signatureStr, true,
new CryptoPP::SignatureVerificationFilter(
verifier_sha256, NULL,
CryptoPP::SignatureVerificationFilter::THROW_EXCEPTION
) // SignatureVerificationFilter
); // StringSource
}
catch( CryptoPP::Exception& e )
{
std::cerr << "ERROR: " << e.what() << std::endl;
}
catch( ... )
{
std::cerr << "ERROR: Unknown verify signature error" << std::endl;
}
}
我错过了什么?
我将非常感谢任何帮助! 提前致谢!
最佳答案
How it is possible to verify a digital signature with the crypto++ library?
嗯,当你知道去哪里寻找时,这个问题就很容易了。来自 Crypto++ wiki RSA Signature Schemes :
RSA::PrivateKey privateKey = ...;
RSA::PublicKey publicKey = ...;
////////////////////////////////////////////////
// Setup
string message = "RSA-PSSR Test", signature, recovered;
////////////////////////////////////////////////
// Sign and Encode
RSASS<PSSR, SHA1>::Signer signer(privateKey);
StringSource ss1(message, true,
new SignerFilter(rng, signer,
new StringSink(signature),
true // putMessage for recovery
) // SignerFilter
); // StringSource
////////////////////////////////////////////////
// Verify and Recover
RSASS<PSSR, SHA1>::Verifier verifier(publicKey);
StringSource ss2(signature, true,
new SignatureVerificationFilter(
verifier,
new StringSink(recovered),
THROW_EXCEPTION | PUT_MESSAGE
) // SignatureVerificationFilter
); // StringSource
cout << "Verified signature on message" << endl;
cout << "Message: " << recovered << endl;
CryptoPP::RSASS<CryptoPP::PSS, CryptoPP::SHA256>::Verifier verifier_sha256(pubKeyRaw);
几个问题:
- 应该是
PSS
(带附录的签名方案)还是PSSR
(带恢复的签名方案)? - 您确定它不是 PKCS1v15 等吗?
- 如果是恢复方案,签名是在十六进制编码的
signatureStr
的开头还是结尾?
这个原始的Integer
初始化可能是错误的。 Crypto++ 将尝试将字符串解析为十进制整数,而不是十六进制整数,因为缺少 0x
前缀和 h
后缀(应存在其中之一)。
您应该添加前缀、后缀或使用字节数组构造函数。字节数组构造函数如下所示。
std::string pupKeyStr ("e0c3851114c758fb...");
string pupKeyBin;
StringSource ss1(pupKeyStr, true,
new HexDecoder(
new StringSink(pupKeyBin)
)
);
CryptoPP::Integer pup_key_cast( (unsigned char*)pupKeyBin.data(), pupKeyBin.size() );
StringSource( signatureStr, true, ...
...
这可能是错误的。您可能需要类似的东西:
string signatureBin;
StringSource ss1(signatureStr, true,
new HexDecoder(
new StringSink(signatureBin)
)
);
StringSource ss2(signatureBin, true,
new SignatureVerificationFilter(...
...
我使用 PSSA
和 PSSR
尝试了带有二进制签名的代码。两者都不起作用。我也尝试过 SignatureVerificationFilter's SIGNATURE_AT_BEGIN
and SIGNATURE_AT_END
。两者都不起作用。我尝试了 SHA1
和 RSASSA_PKCS1v15_SHA_Verifier
的组合。没有任何效果。
你能准确验证你拥有什么吗?
关于c++ - 使用 crypto++ 库进行 RAW RSA 签名验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11144239/