C# 使用RSACryptServiceProvider对来自服务器的哈希进行签名,然后从客户端验证哈希

C# 使用RSACryptServiceProvider对来自服务器的哈希进行签名,然后从客户端验证哈希,c#,.net,rsa,C#,.net,Rsa,您好,我一直在互联网上寻找,我无法找到一个解决我的签名和验证问题的方法。首先,我想确保我在理解发生了什么事情时走在正确的轨道上,所以请纠正我。在签名方面,服务器首先创建两个密钥,一个公钥,一个私钥。然后,服务器将数据文本、公钥、然后散列和加密(使用其私钥)数据文本放入文件中。服务器将文件发送给客户端,客户端通过获取文件中的公钥开始验证数据,并使用公钥解密加密的数据。最后,客户端对文本数据使用哈希算法(与服务器相同),并将其与解密的数据进行比较 如果没有问题,那么我不明白为什么我的代码不起作用:

您好,我一直在互联网上寻找,我无法找到一个解决我的签名和验证问题的方法。首先,我想确保我在理解发生了什么事情时走在正确的轨道上,所以请纠正我。在签名方面,服务器首先创建两个密钥,一个公钥,一个私钥。然后,服务器将数据文本、公钥、然后散列和加密(使用其私钥)数据文本放入文件中。服务器将文件发送给客户端,客户端通过获取文件中的公钥开始验证数据,并使用公钥解密加密的数据。最后,客户端对文本数据使用哈希算法(与服务器相同),并将其与解密的数据进行比较

如果没有问题,那么我不明白为什么我的代码不起作用:

服务器:

string name = textBox1.Text;
string GUID = textBox2.Text;
string startDate = textBox3.Text;
string EndDate = textBox4.Text;
string macAddress = GetMacAddress();
FileStream fs = File.Create(@"cert.txt");
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
UnicodeEncoding ByteConverter = new UnicodeEncoding();
StreamWriter write = new StreamWriter(fs);
write.Write(name + "\r\n");
write.Write(GUID + "\r\n");
write.Write(startDate + "\r\n");
write.Write(EndDate + "\r\n");
write.Write(macAddress + "\r\n");
string pkey = RSA.ToXmlString(false);
write.Write(pkey + "\r\n");
SHA1Managed Sha = new SHA1Managed();
string info = name + GUID + startDate + EndDate + macAddress;
byte [] hashed = Sha.ComputeHash(Encoding.UTF8.GetBytes(info));
byte []signature = RSA.SignData(hashed,CryptoConfig.MapNameToOID("SHA1"));
write.Write(Convert.ToBase64String(signature));
textBox5.Text = Convert.ToBase64String(hashed);
write.Close();
fs.Close();
客户:

FileStream fsSource = new FileStream(@"cert.txt", FileMode.Open,              FileAccess.Read);
StreamReader reader = new StreamReader(fsSource);
string name = reader.ReadLine();
string GUID = reader.ReadLine();
string startDate = reader.ReadLine();
string EndDate = reader.ReadLine();
string macAddress = reader.ReadLine();
string pkey = reader.ReadLine();
string signed = reader.ReadLine();
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSA.FromXmlString(pkey);
string info = name + GUID + startDate + EndDate + macAddress;
SHA1Managed Sha = new SHA1Managed();
byte[] checkinghash = Sha.ComputeHash(Encoding.UTF8.GetBytes(info));
if (RSA.VerifyHash(checkinghash, CryptoConfig.MapNameToOID("SHA1"), Encoding.UTF8.GetBytes(signed)))
{
    Console.WriteLine("verfied");
}
else
{
    Console.WriteLine("denied");
}
Console.WriteLine();
//Console.WriteLine(signed);
Console.ReadKey();
这总是会产生拒绝,因为我不确定是否丢失了公钥,或者这样做是否错误。

您的问题是 您可以在服务器端使用SignData

byte []signature = RSA.SignData(hashed,CryptoConfig.MapNameToOID("SHA1"));
但是在你的客户机上你使用VerifyHash

if (RSA.VerifyHash(checkinghash, CryptoConfig.MapNameToOID("SHA1"), Encoding.UTF8.GetBytes(signed)))
在服务器上,必须使用SignHash

byte []signature = RSA.SignHash(hashed,CryptoConfig.MapNameToOID("SHA1"));
此外,您还必须更改下面的if

if (RSA.VerifyHash(checkinghash, CryptoConfig.MapNameToOID("SHA1"),Convert.FromBase64String(signed)))

感谢您的帮助,我按照您的建议更改了代码,但在验证哈希时仍然显示为拒绝。哇,非常感谢您的帮助,它现在可以工作了!我已经在网上找了几个小时的例子,我不敢相信这仅仅是两个简单的改变。。。