Ensuring Data Integrity with Hash Codes
A hash value is a numeric value of a fixed length that uniquely identifies data. Hash values represent large amounts of data as much smaller numeric values, so they are used with digital signatures. You can sign a hash value more efficiently than signing the larger value. Hash values are also useful for verifying the integrity of data sent through insecure channels. The hash value of received data can be compared to the hash value of data as it was sent to determine whether the data was altered.
This topic describes how to generate and verify hash codes by using the classes in the System.Security.Cryptography namespace.
Generating a Hash
The managed hash classes can hash either an array of bytes or a managed stream object. The following example uses the SHA1 hash algorithm to create a hash value for a string. The example uses the UnicodeEncoding class to convert the string into an array of bytes that are hashed by using the SHA1Managed class. The hash value is then displayed to the console.
Imports System
Imports System.Security.Cryptography
Imports System.Text
Module Program
Sub Main()
Dim HashValue() As Byte
Dim MessageString As String = "This is the original message!"
'Create a new instance of the UnicodeEncoding class to
'convert the string into an array of Unicode bytes.
Dim UE As New UnicodeEncoding()
'Convert the string into an array of bytes.
Dim MessageBytes As Byte() = UE.GetBytes(MessageString)
'Create a new instance of the SHA1Managed class to create
'the hash value.
Dim SHhash As New SHA1Managed()
'Create the hash value from the array of bytes.
HashValue = SHhash.ComputeHash(MessageBytes)
'Display the hash value to the console.
Dim b As Byte
For Each b In HashValue
Console.Write("{0} ", b)
Next b
End Sub
End Module
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
class Class1
{
static void Main(string[] args)
{
byte[] HashValue;
string MessageString = "This is the original message!";
//Create a new instance of the UnicodeEncoding class to
//convert the string into an array of Unicode bytes.
UnicodeEncoding UE = new UnicodeEncoding();
//Convert the string into an array of bytes.
byte[] MessageBytes = UE.GetBytes(MessageString);
//Create a new instance of the SHA1Managed class to create
//the hash value.
SHA1Managed SHhash = new SHA1Managed();
//Create the hash value from the array of bytes.
HashValue = SHhash.ComputeHash(MessageBytes);
//Display the hash value to the console.
foreach (byte b in HashValue)
{
Console.Write("{0} ", b);
}
}
}
This code will display the following string to the console:
59 4 248 102 77 97 142 201 210 12 224 93 25 41 100 197 213 134 130 135
Verifying a Hash
Data can be compared to a hash value to determine its integrity. Usually, data is hashed at a certain time and the hash value is protected in some way. At a later time, the data can be hashed again and compared to the protected value. If the hash values match, the data has not been altered. If the values do not match, the data has been corrupted. For this system to work, the protected hash must be encrypted or kept secret from all untrusted parties.
The following example compares the previous hash value of a string to a new hash value. This example loops through each byte of the hash values and makes a comparison.
Imports System
Imports System.Security.Cryptography
Imports System.Text
Module Module1
Sub Main()
'This hash value is produced from "This is the original message!"
'using SHA1Managed.
Dim SentHashValue As Byte() = {59, 4, 248, 102, 77, 97, 142, 201, 210, 12, 224, 93, 25, 41, 100, 197, 213, 134, 130, 135}
'This is the string that corresponds to the previous hash value.
Dim MessageString As String = "This is the original message!"
Dim CompareHashValue() As Byte
'Create a new instance of the UnicodeEncoding class to
'convert the string into an array of Unicode bytes.
Dim UE As New UnicodeEncoding()
'Convert the string into an array of bytes.
Dim MessageBytes As Byte() = UE.GetBytes(MessageString)
'Create a new instance of the SHA1Managed class to create
'the hash value.
Dim SHhash As New SHA1Managed()
'Create the hash value from the array of bytes.
CompareHashValue = SHhash.ComputeHash(MessageBytes)
Dim Same As Boolean = True
'Compare the values of the two byte arrays.
Dim x As Integer
For x = 0 To SentHashValue.Length - 1
If SentHashValue(x) <> CompareHashValue(x) Then
Same = False
End If
Next x
'Display whether or not the hash values are the same.
If Same Then
Console.WriteLine("The hash codes match.")
Else
Console.WriteLine("The hash codes do not match.")
End If
End Sub
End Module
using System;
using System.Security.Cryptography;
using System.Text;
class Class1
{
static void Main()
{
//This hash value is produced from "This is the original message!"
//using SHA1Managed.
byte[] SentHashValue = { 59, 4, 248, 102, 77, 97, 142, 201, 210, 12, 224, 93, 25, 41, 100, 197, 213, 134, 130, 135 };
//This is the string that corresponds to the previous hash value.
string MessageString = "This is the original message!";
byte[] CompareHashValue;
//Create a new instance of the UnicodeEncoding class to
//convert the string into an array of Unicode bytes.
UnicodeEncoding UE = new UnicodeEncoding();
//Convert the string into an array of bytes.
byte[] MessageBytes = UE.GetBytes(MessageString);
//Create a new instance of the SHA1Managed class to create
//the hash value.
SHA1Managed SHhash = new SHA1Managed();
//Create the hash value from the array of bytes.
CompareHashValue = SHhash.ComputeHash(MessageBytes);
bool Same = true;
//Compare the values of the two byte arrays.
for (int x = 0; x < SentHashValue.Length; x++)
{
if (SentHashValue[x] != CompareHashValue[x])
{
Same = false;
}
}
//Display whether or not the hash values are the same.
if (Same)
{
Console.WriteLine("The hash codes match.");
}
else
{
Console.WriteLine("The hash codes do not match.");
}
}
}
If the two hash values match, this code displays the following to the console:
The hash codes match.
If they do not match, the code displays the following:
The hash codes do not match.