14.4 Verify a Hash Code


Problem

You need to verify a password or confirm that a file remains unchanged by comparing two hash codes.

Solution

Convert both the old and the new hash codes to hexadecimal code strings, Base64 strings, or byte arrays and compare them.

Discussion

You can use hash codes to determine if two pieces of data (such as passwords or files) are the same, without the need to store, or even maintain access to, the original data. To determine if data changes over time, you must generate and store the original data's hash code. Later, you can generate another hash code for the data and compare the old and new hash codes, which will show if any change has occurred. The format in which you store the original hash code will determine the most appropriate way to verify a newly generated hash code against the stored one.

Note  

Many recipes in this chapter use the ToString method of the class System.BitConverter to convert byte arrays to hexadecimal string values for display. Although easy to use and appropriate for display purposes, you might find this approach inappropriate for use when storing hash codes because it places a hyphen (-) between each byte value (for example, 4D-79-3A-C9- ). In addition, the BitConverter class doesn't provide a method to parse such a string representation back into a byte array.

Hash codes are often stored in text files, either as hexadecimal strings (for example, 89D22213170A9CFF09A392F00E2C6C4EDC1B0EF9 ), or as Base64- encoded strings (for example, idIiExcKnP8Jo5LwDixsTtwbDvk= ). Alternatively, hash codes may be stored in databases as raw byte values. Regardless of how you store your hash code, the first step in comparing old and new hash codes is to get them both into a common form.

This first example converts a new hash code (a byte array) to a hexadecimal string for comparison to an old hash code. Other than the BitConverter.ToString method we discussed earlier, the .NET Framework class library doesn't provide an easy method to convert a byte array to a hexadecimal string. You must program a loop to step through the elements of the byte array, convert each individual byte to a string, and append the string to the hexadecimal string representation of the hash code. The use of a System.Text.StringBuilder avoids the unnecessary creation of new strings each time the loop appends the next byte value to the result string. (See recipe 2.1 for more details.)

 // A method to compare a newly generated hash code with an  // existing hash code that's represented by a hex code string private static bool VerifyHexHash(byte[] hash, string oldHashString) {              // Create a string representation of the hash code bytes.     System.Text.StringBuilder newHashString =          new System.Text.StringBuilder(hash.Length);              // Append each byte as a 2 character upper case hex string.     foreach (byte b in hash) {         newHashString.AppendFormat("{0:X2}", b);     }              // Compare the string representations of the old and new hash      // codes and return the result.     return (oldHashString == newHashString.ToString()); } 

In this second example, the new hash code is a byte array and the old hash code is a Base64 encoded string. The code very neatly encodes the new hash code as a Base64 string and performs a straightforward string comparison of the two values.

 // A method to compare a newly generated hash code with an // existing hash code that's represented by a Base64 encoded string. private static bool VerifyB64Hash(byte[] hash, string oldHashString) {              // Create a Base64 representation of the hash code bytes.     string newHashString = System.Convert.ToBase64String(hash);           // Compare the string representations of the old and new hash      // codes and return the result.     return (oldHashString == newHashString); } 

This final example compares two hash codes represented as byte arrays. The .NET Framework class library doesn't include a method that performs this type of comparison, and so you must program a loop to compare the elements of the two arrays. This code uses a few time-saving techniques, namely ensuring that the byte arrays are the same length before starting to compare them, and returning false on the first difference found.

 // A method to compare a newly generated hash code with an // existing hash code represented by a byte array. private static bool VerifyByteHash(byte[] hash, byte[] oldHash) {              // If either array is null, or the arrays are different lengths     // then they are not equal.     if (hash == null  oldHash == null  hash.Length != oldHash.Length)         return false;                  // Step through the byte arrays and compare each byte value.     for (int count = 0; count < hash.Length; count++) {         if (hash[count] != oldHash[count]) return false;     }          // Hash codes are equal.     return true; } 



C# Programmer[ap]s Cookbook
C# Programmer[ap]s Cookbook
ISBN: 735619301
EAN: N/A
Year: 2006
Pages: 266

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