When implementing any type of encryption into an application, we must first take into consideration the output. For early encryptions such as RC2 or RC4, there was a need to reverse engineer the initial value. In cases where we're working primarily with passwords or other user input-based validations, such as social security numbers or the last four digits of their credit card number, we can just validate that the stored encrypted value is identical to what was entered in by the user.
To implement an MD5 hashing algorithm in your application, it's suggested to use a central static method if it's to be used by multiple classes, or you may opt to attach it specifically with a certain class if and only if it's the only one that will utilize it. For instance, in most web-based applications, the MD5 hashing algorithm will be used to validate user passwords, and it should only be stored in the data layer. In this example, we'll use a static method.
/// <summary>
/// Encrypts the string to a byte array using the MD5 Encryption Algorithm.
/// <see cref="System.Security.Cryptography.MD5CryptoServiceProvider"/>
/// <param name="ToEncrypt">System.String. Usually a password.</param>
/// <returns>System.Byte[]</returns>
/// </summary>
public static byte[] MD5Encryption(string ToEncrypt)
{
// Create instance of the crypto provider.
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
// Create a Byte array to store the encryption to return.
byte[] hashedbytes;
// Required UTF8 Encoding used to encode the input value to a usable state.
UTF8Encoding textencoder = new UTF8Encoding();
// let the show begin.
hashedbytes = md5.ComputeHash(textencoder.GetBytes(ToEncrypt));
// Destroy objects that aren't needed.
md5.Clear();
md5 = null;
// return the hased bytes to the calling method.
return hashedbytes;
}
From this example, we're only implementing the bare MD5 algorithm. The MD5 classes are found in the System.Security.Cryptography namespace and help in adding the ease of use to .NET-based languages and applications. The input for the overloaded public method ComputeHash are System.Byte[], System.IO.Stream, and a more precise encryption where a combination of the System.Byte[] and the offset/count is input. We can also use the System.Text.UTF8Encoding class to get the byte array from our string or to use System.Convert.FromBase64. Both will work; however, in this example, we'll use the UTF8Encoding class.
How do I store this byte array?
In Micrsoft SQL Server, you can store the output of an MD5 encryption in a field type of binary. You may run queries to validate by using parameters of the binary type. This is more secure than validating against strings because SQL Server will not case match strings by default and may lead to false validations in case sensitive scenarios. For other data storage mediums, please consult the proper documentation.
An example of an MD5 encryption in runtime is as follows.
// use the password with a upper case M in my.
System.Diagnostics.Debug.WriteLine("MD5Encryption(\"MyPassw0rd1sTh1s\")");
byte[] bytes = MD5Encryption("MyPassw0rd1sTh1s");
for (int i=0;i<bytes.Length;i++)
{
System.Diagnostics.Debug.Write(bytes[i].ToString());
if (i < bytes.Length -1)
System.Diagnostics.Debug.Write(", ");
}
System.Diagnostics.Debug.WriteLine("");
// change the password to have a lowercase my.
System.Diagnostics.Debug.WriteLine("MD5Encryption(\"myPassw0rd1sTh1s\")");
bytes = MD5Encryption("myPassw0rd1sTh1s");
for (int i=0;i<bytes.Length;i++)
{
System.Diagnostics.Debug.Write(bytes[i].ToString());
if (i < bytes.Length -1)
System.Diagnostics.Debug.Write(", ");
}
The output is:
MD5Encryption("MyPassw0rd1sTh1s")
160, 163, 28, 224, 220, 31, 34, 25, 105, 73, 210, 22, 244, 57, 35, 160
MD5Encryption("myPassw0rd1sTh1s")
135, 149, 230, 149, 156, 59, 78, 203, 22, 243, 45, 198, 161, 73, 87, 76
As you can see from this example, a single change in case will completely alter the byte array returned hence giving you the powerful encryption for your web application.