Creating a Hash Value
Next, you need a hashing algorithm to create the hash value for the random string passed into this function. However, that doesn't solve all the problems. A spoofer can easily spot the vulnerability in this technique once he notices that all the page does is send a hashed version of a string to the client, comparing that with the hashed version of whatever the user entered. He can create a spoof to:
- Post a hash version of any string he chooses.
- Post his chosen string in clear text to the server's processing logic.
All that the processing logic does is:
- Hash the clear text.
- Compare that value with the posted hash value.
So, you need a way to prevent the spoofer from simply hashing any string he chooses. Yet, because hashes are a "one-way" function, you need to be able to verify that the hash could only have been generated from your application.
Creating a Unique Hash
This is where a Machine Authentication Check (MAC) comes in handy.
Just as the name implies, a MAC is a technique to generate a unique hash value that could only come from one particular machine. You append this unique value to the plain text before hashing the whole message. When you do that, only the machine that knows the secret key can verify the hash. No one else will know how to generate the exact same hash even if they know the plain text message. Here are the steps:
- Generate a unique GUID key (MAC key) with the Guid.NewGuid function.
- Save this MAC key in the Web.Config file of the application.
- Retrieve the stored MAC key and append it to the string you want to hash.
- Hash the entire message.
- Save the message in a cookie.
- To verify, all your form needs to do is to HTTP-POST the string that the user entered for verification.
- When the application receives this string, append the same MAC key from the Web.Config file to the end of this string.
- Hash the whole message.
- Retrieve the cookie value from the HTTP Request Headers and compare the message in Point (8) with the cookie value in Point (4)
- If the values don't match, you either have a spoof or the user simply read or entered the captcha text incorrectly.
As you can see from the steps below, no one can produce the same hash even for the same plain text if they do not know what the MAC key is. This prevents Man-In-the-Middle (MITM) attacks as well. In fact, the ASP.NET EnableViewStateMAC
command uses this model to provide added security against MITM attacks. Here's the code for the hashing function, which you'll find in the RandomStringGenerator.vb
class file in the downloadable code
Public Shared Function HashMACMe(ByVal s As String) _
Dim b As Byte
Dim HashValue() As Byte
Dim retString As String
' 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(s & _
' 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)
' Return a hexadecimal representation of the string
For Each b In HashValue
retString += b.ToString("X2")
The code reads the MAC key from the web.config
file and appends it to the initial string before hashing the final output message. The page sends that hash value as a cookie.