使用PHP代码对消息进行签名(使用phpseclib 2.0):
function sign($plaintext, $key, $password) {
$rsa = new RSA();
$rsa->setPassword($password);
$rsa->loadKey(file_get_contents($key));
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
$signature = $rsa->sign(hash('sha256', $plaintext));
return base64_encode($signature);
}
公钥和私钥格式为PEM。我需要用C#验证这个签名。我正在尝试此代码,但它返回false:
public static bool VerifyData(string originalMessage, string signedMessage, RSAParameters publicKey)
{
bool success = false;
using (var rsa = new RSACryptoServiceProvider())
{
var encoder = new UTF8Encoding();
byte[] bytesToVerify = encoder.GetBytes(originalMessage);
byte[] signedBytes = Convert.FromBase64String(signedMessage);
try
{
rsa.ImportParameters(publicKey);
SHA256Managed Hash = new SHA256Managed();
byte[] hashedData = Hash.ComputeHash(bytesToVerify);
success = rsa.VerifyData(hashedData, CryptoConfig.MapNameToOID("SHA256"), signedBytes);
}
catch (CryptographicException e)
{
Console.WriteLine(e.Message);
}
finally
{
rsa.PersistKeyInCsp = false;
}
}
return success;
}
用法:
RSACryptoServiceProvider rsa = PemKeyUtils.PemKeyUtils.GetRSAProviderFromPemFile("public.key");
MessageBox.Show(VerifyData("my message", @"ZpQMPYlMIgME/H0sRYBnyEf/yJ/eBc5bznYZ2nMFn/I6Ts3u8P3x0QgzbUxPnhUgfKhcrEC2UgffyzWzCfwT3Bs+lm6Q89N5bkWK08WKnWaFxr2GQ6+gNyPyUKUgfy851xIHU7EMR6bZt/IndPC+lAAXSxxddPwLelrI8ktgyMVvMUzfCh3AeNCBuY5sSRwkAKH2myPBThJKNjKSZVEb4tO4oiPPWlBuifqmWvbQeMFuKANY0dZNCUFVjlnkaHnwVNzVs1BhNTEML2MKmWvKofafbtcG8J1F+7PapppZwT7OFqhosCSrrzRX49cR4y/7b0syJozmJSebKDpy6FPefA==", rsa.ExportParameters(false)).ToString());
来自this answer的PemKeyUtils课程。
出了什么问题?如何用C#验证签名?
答案 0 :(得分:1)
VerifyData()
计算哈希本身,因此您最终会在C#代码中对数据进行两次哈希处理。只需将数据直接提供给VerifyData()
,而无需自己进行散列。
编辑:好的,现在我看到你在php端也是两次哈希,第一次用SHA1,第二次用SHA256。只需使用SHA256哈希一次,就像显示in the examples一样。
function sign($plaintext, $key, $password) {
$rsa = new RSA();
$rsa->setPassword($password);
$rsa->loadKey(file_get_contents($key));
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
$rsa->setHash('sha256')
$signature = $rsa->sign($plaintext);
return base64_encode($signature);
}