问题描述
我有一个非常简单的.Net控制台应用程序,我将在此处粘贴该应用程序,该应用程序执行RSA签名验证,并且可以在.Net Core 3.1上完美运行。但是,.net 4.8控制台应用程序上完全相同的代码(复制粘贴,不作任何更改)表示签名无效。
我不知道发生了什么。在我测试过的所有其他语言甚至在线RSA签名验证器中,此签名都是可以的。
在两者上都使用Nuget BouncyCastle 1.8.6.1。
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
public class Program
{
static void Main()
{
byte[] publicKeyData = Convert.FromBase64String("LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUE1RGxFVVRtQUF0ZGIvVXZGYnpiWQpxbVJYNGZ6VW80WGhIbTk1VDRvbS9OaVplbFBNYzFOUjNNMVV0OFIyQkdRdmt2MndEUUkzblk2ZklLeUtWM3VVCjR4ZTIvMW1IQkdaSVB5WHRLKzdaelJJbkl1aTVtT0x2R2FTOVBlaFJSMTVvTTZXT3pweTdOay9QRjlUUHltWEEKWEZnQWZTZFo3bUx4QldqUktjMGorUTNZRGZuWi9OMzUzZUJEc1FWN2tkamVFYVpmK3RUZll5eFVpY2RTUjZVUgpsOUl4YW5yc2RqVjF1TndmWm5yYTdDVTFhcElCcjNFeDZBb20yWDVtNjZ4TjRXeVJHRCtOS3ZBeitNVHZkSU4vClNLVU1UMnA0aEpWc3FiZ2hGN2FZeDYxNGxHbmN5dTZQNDQ4QjlBcjh2R0NLbDRnMGl0eUtjbGJSZS9wMjh2U2oKWkxwYkVjZkY2eHlJYlJraWZEbHJITUlQS1JkazRIV25wamQvaEdHN2lZN1VWYWJuUmxpVUExVDQ3T2kyaENVNwoxKzVkT1F4dDdRNVFxUFNURFNZc1E4M1c5VStmZ0xMYVVWSFA5SzhpdG1qWW1ueFF2a1FqUnc5YUhYTk5Db2M4ClZrdFBnY1A0UFJTZ0dLL2JWbWtIbjBrWDMvclVEZG9zV1dHaURUWnZwRFRKUHo3UVpmbENFRDFzV0xIaEMxOU8KdWtFdEFQYVR5VkJ5RC9yUURoTWJyb2RIVmRJNjhZeE5UdnNpU2NxdlMvZlBmYUVUcUJsVzJpQXVndE5TZGIzSApEOFVFUUgzTUE0K044RXVtK1o5bzQ2Vnk2c0hOVytVVE0wRDVwOXBvWWEwV1dxQ0hLc2ZqbFcyN0dIaDF1WDZKCmNHd0NBc1pBT2N6MEpPRWVuSDFtYXhrQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=");
string decodedPublicKeyString = Encoding.UTF8.GetString(publicKeyData);
string signedData = "RHClqUohXp5QOvBAYqTMa63PuYXahqKEDUIdCYfA/qq1mT18QSVIu5gneYbYjAQH4dWE5wytMnIihNZkFcY06WjIeTwJJVHZPmp/SGQvO44ouF2Qhb6n9HmgdqLzL1gPUVeElyeytDvcaRgkI2tqIZ+3a1QERVpH49xGQzf2N1YcFycOrm08CHO3o9jTWJrtURntgOV9cGUStZy2mEJ5CvNo8+5Fniidsjpn4Bem/34PdFNRjVRgrVVqVjaB6ICB6KTMPzd/jPF02cPGA5n7j5Stn9DpU1uyicEhCsMK/zxrfSYpKdXH74fjIP7Rw9HlWnAVlLv/pkVpCcRLLn7iW1V6MPvzuL9rft2QK61RDSo4Ntka6a48+FJPB2v9pTY8qu4jIUcpLGX+wYnHCt9nZnZ4UlFh6BKDFrpH1tZJ2XreS2qGlSiBii0j30VyjCinEz8rIFFes7kGbWm/6jdXZliWbgPpZ7shEVSTwPDy6UVeD0LP9m/OxLNfCF31bOLkacxA8qv5PvbntWUcuNsUqdrk5YKcaDdQq4texWm1CQtBs7gYVwARYHusHi6ISUCHGN0RnULcPLa7jfZVq/y56DV0tuxhxsxyu9BpCx6Rm5AlYJJcgRyRRsaldivHBdvNJZCDPIVBBmpbpfKoctwWSvROmnirCFc9iQb8gnNNtlc=";
var signedBytes = Convert.FromBase64String(signedData);
VerifyWithPublicKey("12345789",signedBytes,decodedPublicKeyString);
}
private static bool VerifyWithPublicKey(string data,byte[] signedHash,string decodedPublicKey)
{
try
{
using (RSA rsa = RSA.Create())
{
byte[] hash;
using (SHA256 shaM = SHA256.Create())
{
hash = shaM.ComputeHash(Encoding.ASCII.GetBytes(data));
}
using (var keyreader = new StringReader(decodedPublicKey))
{
var pemReader = new PemReader(keyreader);
var y = (RsaKeyParameters)pemReader.Readobject();
var rsaParameters = new RSAParameters();
rsaParameters.Modulus = y.Modulus.ToByteArray();
rsaParameters.Exponent = y.Exponent.ToByteArray();
rsa.ImportParameters(rsaParameters);
RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(rsa);
RSADeformatter.SetHashAlgorithm("SHA256");
if (RSADeformatter.VerifySignature(hash,signedHash))
{
Console.WriteLine("The signature was verified.");
return true;
}
else
{
Console.WriteLine("The signature was not verified.");
return false;
}
}
}
}
catch (CryptographicException e)
{
Console.WriteLine(e.Message);
}
return false;
}
}
解决方法
在我的计算机上运行,对于4.6.2和4.7.2均产生false
。但是,更改
rsaParameters.Modulus = y.Modulus.ToByteArray();
rsaParameters.Exponent = y.Exponent.ToByteArray();
到
rsaParameters.Modulus = y.Modulus.ToByteArrayUnsigned();
rsaParameters.Exponent = y.Exponent.ToByteArrayUnsigned();
似乎可以解决此问题。我希望这对您有用。