Reputation: 11
Hi there I've been looking all over the internet and I can't quite find a solution to my problem of signing and verifying. First of all I want to make sure I'm on the right track when it comes to understanding what happens so please correct me. The first thing when it comes to signing is that the server first creates two keys one public and one private. The server then puts data text, the public key, and then hashed and encrypted(using it's private key) data text on a file. The server sends the file to the client and the client starts to verify the data by getting the public key in the file and uses that to decrypt the encrypted data. Finally, the client uses the hash algorithm (same one as the server) to the text data and compares it to the data that was decrypted.
If this is all right then I don't understand why my code isn't working:
Server:
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();
Client:
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();
This always produces denied as I'm not sure if I'm missing the public key or if this is wrong way to go about it.
Upvotes: 1
Views: 6850
Reputation: 479
Your problem is you use SignData On The Server Side
byte []signature = RSA.SignData(hashed,CryptoConfig.MapNameToOID("SHA1"));
but on your client you use VerifyHash
if (RSA.VerifyHash(checkinghash, CryptoConfig.MapNameToOID("SHA1"), Encoding.UTF8.GetBytes(signed)))
on your server You must use SignHash
byte []signature = RSA.SignHash(hashed,CryptoConfig.MapNameToOID("SHA1"));
and also you must change the if like below
if (RSA.VerifyHash(checkinghash, CryptoConfig.MapNameToOID("SHA1"),Convert.FromBase64String(signed)))
Upvotes: 2