5. Validating Hash Codes
Now that you have seen how to create hash
codes (playing the role of Alice), we will show you how to validate
them, playing the role of Bob. Remember that Bob receives a hash code
and a message from Alice. He generates his own hash code and checks
that it matches the one that he received. Example 1 shows a simple approach to validating hash
codes:
Example 1. Validating a hash code
# C#
using System; using System.Text; using System.Security.Cryptography;
class HashCodeValidation {
private static byte[] ParseHashCodeString(string p_hash_code_string) { // split the hash code on spaces string[] x_elements = p_hash_code_string.Split(' '); // create a byte array to hold the elements byte[] x_hash_code_array = new byte[x_elements.Length]; // parse each string element into a byte for (int i = 0; i < x_elements.Length; i++) { x_hash_code_array[i] = Byte.Parse(x_elements[i], System.Globalization.NumberStyles.HexNumber); } // return the byte array return x_hash_code_array; }
private static bool CompareHashCodes(byte[] x_hash_code1, byte[] x_hash_code2) {
// check that the hash codes are the same length if (x_hash_code1.Length == x_hash_code2.Length) { // run through the hash code and check // each value in turn for (int i = 0; i < x_hash_code1.Length; i++) { if (x_hash_code1[i] != x_hash_code2[i]) { // the byte at this location is different // in each hash code return false; } } // the hash codes are the same return true; } else { // the hash codes contain different numbers of // bytes and so cannot be the same return false; } }
public static bool ValidateHashCode(string p_hash_algorithm, string p_hash_string, byte[] p_data) {
// parse the hash code string into a byte array byte[] x_hash_code = ParseHashCodeString(p_hash_string);
// create the hashing algorithm object using the // name argument HashAlgorithm x_hash_alg = HashAlgorithm.Create(p_hash_algorithm);
// compare the hash codes return CompareHashCodes(x_hash_code, x_hash_alg.ComputeHash(p_data)); }
static void Main(string[] args) { // define the message data that Alice sent to Bob string x_message_data = "Programming .NET Security"; // covert the message data into a byte array byte[] x_message_bytes = Encoding.Default.GetBytes(x_message_data); // define the hash code that Alice sent to Bob string x_hash_string = "E1 62 9F C2 96 85 C3 A4 5B 94 97 57 D8 9C 65 78"; // define the name of the hashing algorithm that Alice used string x_algorithm_name = "MD5";
// validate the hash code and write out the result bool x_result = ValidateHashCode(x_algorithm_name, x_hash_string, x_message_bytes);
if (x_result) { Console.WriteLine("The hash code is valid"); } else { Console.WriteLine("The hash code is invalid"); } } } # Visual Basic .NET
Imports System.Security.Cryptography Imports System.Text
Module HashCodeValidation
Public Function ParseHashCodeString(ByVal p_hash_code_string _ As String) As Byte( ) ' split the hash code on spaces Dim x_elements( ) As String = p_hash_code_string.Split(" "c) ' create a byte array to hold the elements Dim x_hash_code_array( ) As Byte = New Byte(x_elements.Length - 1) {} ' parse each string element into a byte Dim i As Integer For i = 0 To x_elements.Length - 1 Step i + 1 x_hash_code_array(i) = Byte.Parse(x_elements(i), _ System.Globalization.NumberStyles.HexNumber) Next ' return the bye array Return x_hash_code_array End Function
Private Function CompareHashCodes(ByVal x_hash_code1( ) As Byte, _ ByVal x_hash_code2( ) As Byte) As Boolean ' check that the hash codes are the same length If x_hash_code1.Length = x_hash_code2.Length Then ' run through the hash code and check ' each value in turn Dim i As Integer For i = 0 To x_hash_code1.Length - 1 Step i + 1 If x_hash_code1(i) <> x_hash_code2(i) Then ' the byte at this location is different ' in each hash code Return False End If Next ' the hash codes are the same Return True Else ' the hash codes contain different numbers of ' bytes and so cannot be the same Return False End If End Function
Public Function ValidateHashCode(ByVal p_hash_algorithm As String, _ ByVal p_hash_string As String, ByVal p_data( ) As Byte) As Boolean
' parse the hash code string into a byte array Dim x_hash_code( ) As Byte = ParseHashCodeString(p_hash_string)
' create the hashing algorithm object using the ' name argument Dim x_hash_alg As HashAlgorithm = HashAlgorithm.Create(p_hash_algorithm)
' compare the hash codes Return CompareHashCodes(x_hash_code, x_hash_alg.ComputeHash(p_data)) End Function
Sub Main( ) ' define the message data that Alice sent to Bob Dim x_message_data As String = "Programming .NET Security" ' covert the message data into a byte array Dim x_message_bytes( ) As Byte = Encoding.Default.GetBytes(x_message_data) ' define the hash code that Alice sent to Bob Dim x_hash_string As String = _ "E1 62 9F C2 96 85 C3 A4 5B 94 97 57 D8 9C 65 78" ' define the name of the hashing algorithm that Alice used Dim x_algorithm_name As String = "MD5"
' validate the hash code and write out the result Dim x_result As Boolean = ValidateHashCode(x_algorithm_name, _ x_hash_string, x_message_bytes)
If (x_result) Then Console.WriteLine("The hash code is valid") Else Console.WriteLine("The hash code is invalid") End If End Sub
End Module
|
The first step in validating the hash code is to parse the
information that Bob has received. The format we have used to express
the hash codes is the most commonly used, but you may encounter other
formats.
The
ParseHashCodeString method accepts a string containing a
formatted hash code and produces a byte array. The
CompareHashCodes method takes care of comparing
two arrays of bytes to ensure that they contain
the same hash code.
The
ValidateHashCode method uses the other two methods to
validate a hash code, taking three arguments:
The name of the algorithm that Alice used to create the hash code
The hash code Alice created, expressed as a string of hexadecimal
bytes
The message from Alice, expressed as a string
Parse the hash code string into a byte array, and then create an
instance of the HashAlgorithm class based on the
algorithm name. Assume that Alice and Bob agree on the algorithm that
was used to create the hash codes, or that Alice picks one and
indicates which algorithm she has used by sending some information
along with the message. Notice how you cannot create an instance of
any supported algorithm using the same code statements; this is
another benefit of instantiating algorithms by name.
Finally, calculate a hash code for the message data and compare it to
the one that Bob received from Alice. The example includes a Main
method to demonstrate how to validate the hash code that you
created previously.