Working with Hashes and Digital Signatures


Hashes and digital signatures work hand in hand in order to give your code the ability to sign data as well as verify that the data has not been tampered with.

The sequence of events typically works like this:

  • Your application produces data that needs to be transmitted to another location or to be read by another application.

  • Using your private key, your application creates an encrypted signature from a hash of the data to be transmitted.

  • The data payload, containing both the data and the encrypted signature, is transmitted to a remote location and/or read by another application.

  • The other application decrypts the hashed signature using the sender's public key, and then compares the decrypted hash against a hash that the other application computed on its own using the same hash algorithm. If the computed hash matches the decrypted hash, the other application can be sure that the data has not been tampered with.

Let's take a look at the first half of the process, the hashing of data and the creation of a signature from that hash:

string verifiableMesage = "It was the best of times, it was the worst of times."; SHA1Managed sha = new SHA1Managed(); byte[] hashValue =     sha.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(verifiableMesage)); // now that we have a hash, create a signature based on the hash // re-use Jane's key. StreamReader sr = File.OpenText(@"..\..\..\..\JanesKey.xml"); string janesKey = sr.ReadToEnd(); RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(janesKey); RSAPKCS1SignatureFormatter sigFormatter = new RSAPKCS1SignatureFormatter(rsa); sigFormatter.SetHashAlgorithm("SHA1"); byte[] signedHash = sigFormatter.CreateSignature(hashValue); // write the signed hash to disk FileStream fs = new FileStream(@"..\..\..\..\signedHash.dat", FileMode.Create); fs.Write(signedHash, 0, signedHash.Length) ; fs.Close(); 


Next, we'll need to write some code that reads the signed hash from the data file, computes its own hash, and does a comparison to verify the authenticity of the data. The following is the code contained in a console application that does this:

string verifiableMesage = "It was the best of times, it was the worst of times."; string wrongMessage = "It was the best of times it was the worst of times"; SHA1Managed sha = new SHA1Managed(); byte[] verifiableMessageHash = sha.ComputeHash(     System.Text.ASCIIEncoding.ASCII.GetBytes(verifiableMesage)); byte[] wrongMessageHash = sha.ComputeHash(     System.Text.ASCIIEncoding.ASCII.GetBytes(wrongMessage)); // note that we never manually decrypt the sig, that's done by the sig verifier FileStream fs = new FileStream(@"..\..\..\..\signedHash.dat", FileMode.Open); byte[] fileHash = new byte[fs.Length]; fs.Read(fileHash, 0, (int)fs.Length) ; fs.Close(); // get jane's key so we can decrypt the hash StreamReader sr = File.OpenText(@"..\..\..\..\JanesKey.xml"); string janesKey = sr.ReadToEnd(); sr.Close(); RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(janesKey); RSAPKCS1SignatureDeformatter sigDeformatter = new RSAPKCS1SignatureDeformatter(rsa); sigDeformatter.SetHashAlgorithm("SHA1"); if (sigDeformatter.VerifySignature(verifiableMessageHash, fileHash)) {     Console.WriteLine("The real message is verified as untampered.") ; } if (sigDeformatter.VerifySignature(wrongMessageHash, fileHash) == false) {     Console.WriteLine("The fake message is verified as fake."); } else {     Console.WriteLine("This should statistically never happen."); } Console.ReadLine(); 


The first thing that this code does is create hashes from two different strings. One string is the original and valid data, whereas the other string is missing a comma. If all that I've said about hashing and signatures is true, the missing comma should cause a signed hash validation to fail, simulating data that has been tampered with.

Next the key is loaded from the XML file (in a real-world scenario, the key would probably be coming from an OS-level key container). A signature deformatter is then loaded based on the SHA-1 hashing algorithm.

Finally, two comparisons are made: one comparison against the legitimate hash, and one against the hash that simulates tampered data. When we run the application, the output confirms that the digital signature is doing its job:

The real message is verified as untampered. The fake message is verified as fake. 




Microsoft Visual C# 2005 Unleashed
Microsoft Visual C# 2005 Unleashed
ISBN: 0672327767
EAN: 2147483647
Year: 2004
Pages: 298

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net