【发布时间】:2017-08-27 23:16:38
【问题描述】:
感谢RSACryptoServiceProvider 类,我正在尝试在C# 中对一些字节进行签名,并使用Crypto++ 库在C++ 中对其进行验证。尽管我做了所有尝试,但验证失败了,尽管我确信我的密钥和签名。
在 C# 中,我的签名如下:
var message = "hello";
var bytes = System.Text.Encoding.UTF8.GetBytes(message);
byte[] signedHash;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
// Import the key information.
rsa.ImportParameters(privateKey);
// Sign the data, using SHA256 as the hashing algorithm
signedHash = rsa.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
}
我的密钥生成如下:
CspParameters parameters = new CspParameters();
parameters.KeyNumber = (int)KeyNumber.Signature;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024, parameters))
{
privateKeyInfo = rsa.ExportParameters(true);
publicKeyInfo = rsa.ExportParameters(false);
}
在 C++ 中,我创建了公钥并尝试如下验证:
RSA::PublicKey publicKey;
byte signature[128];
signature[0]= 150;
//....fill up to 127 , corresponds to "signedHash" variable from c# code
signature[127]= 89;
string simplemessage = "hello";
string modulus = "0Z8GUI/rxlXanCCjkiP+c9HyvdlOibst2YD5XmZk4F86aLr7LbLtI7FMnr6rcQZa6RXkAykb5MIbasmkOmkLzSjhdTThnaZyuKBOBoybYB5mDecF2VMXfUIryEBFn4i6y58qhy0BnDnIhucdNXX0px10HL3uYzR2KBTC0lSFFmE=";
string exponent = "AQAB";
char modulusCharred[1024];
strncpy_s(modulusCharred, base64ToHex(modulus).c_str(), sizeof(modulusCharred));
modulusCharred[sizeof(modulusCharred) - 1] = 0;
char exponentCharred[1024];
strncpy_s(exponentCharred, base64ToHex(exponent).c_str(), sizeof(exponentCharred));
exponentCharred[sizeof(exponentCharred) - 1] = 0;
Integer n(modulusCharred);
Integer e(exponentCharred);
publicKey.Initialize(n, e);
AutoSeededRandomPool rnd;
if(!publicKey.Validate(rnd, 3))
throw runtime_error("Rsa public key validation failed"); // no error is thrown
RSASS<PSS, SHA256>::Verifier verifier(publicKey);
bool result = verifier.VerifyMessage((const byte*)simplemessage.c_str(),simplemessage.length(), signature,128);
if(true == result) {
cout << "Signature on message verified" << endl;
} else {
cout << "Message verification failed" << endl; // always fail...
}
模数和指数是从 c# 中使用 rsa.ToXmlString(false) 获得的 xml 复制/过去的。函数base64toHex 由(在另一个 SO 帖子中找到)给出:
std::string base64ToHex(std::string base64String)
{
std::string decodedString, finalString;
CryptoPP::StringSource river(base64String, true,
new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decodedString)));
CryptoPP::StringSource stream(decodedString, true,
new CryptoPP::HexEncoder(new CryptoPP::StringSink(finalString)));
finalString.erase(std::remove(finalString.begin(), finalString.end(), '\n'), finalString.end());
return finalString;
}
我不想使用任何外部文件,只有字节(或字符串)变量。我也不确定我定义验证者的方式:RSASS<PSS, SHA256>::Verifier。
你能帮我解决这个问题吗?
【问题讨论】:
-
RSACryptoServiceProvider 只做 PKCS1_v1.5 签名,它不能做 PSS。所以你需要使用 PKCS 验证器。
-
谢谢,我已将验证器修改为
RSASS<PKCS1v15, SHA256>::Verifier,但问题仍然存在。
标签: c# c++ windows cryptography crypto++