AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=535&pId=-1
Using MD5 Encryption
page
by Kay Lee
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 35663/ 39

What is MD5?

What is MD5, and how is it used today?

Message-Digest Algorithm 5 (MD5) is a one-way hashing algorithm used primarily for digitally signing files and strings.  MD5 does have its weaknesses.  They say a good mixture is an initial compression using a hash-based encryption (MD5 and SHA1) and a more reliable encryption such as RSA.  Rather than going into technical specifics, it's suggested you read RFC 1321.  As mentioned in many online circuits, it's specifically suggested to migrate applications from MD5 to a more reliable encryption method before a wide spread cracking revolution occurs in terms of MD5/SHA1-based encryption.

MD5 is considered to be one of the fastest encryption algorithms with a little safety harness.  Its safety harness is essentially another round of calculations to ensure ultimate security (which has been rumored as broken).  It's utilized heavily in both open and closed source applications and platforms such as Apache and Solaris.

Why should I use MD5 if I know it is not the most secure?

The answer is fairly straightforward: it's fast, it's easy, and it can be powerful if salted.  With a little bit of salt any meal will taste better.  That's the analogy we'll use in this article to enhance the MD5 hashing algorithm to further extend our security without jeapordizing our performance.  The greatest advantage of MD5 is it's speed and ease of use.

What are these security flaws in MD5?

Last month (August 12, 2004), an announcement was made by Antoine Joux in regards to a flaw in the algorithm for MD4 and MD5.  Later that month, a paper was submitted (http://eprint.iacr.org/2004/199.pdf) that detailed collisions.  The paper suggests that it takes about an hour to find the first collision and an estimated 15 minutes to detect the remainder of the hash. 

In a convention held in Santa Barbara (Crypto 2004), it's reported that other collision examples were presented as well as that an onslaught of hackers is developing means of creating these collisions for intrusion purposes.  Apache and Solaris are known to use MD5 heavily in validating file uniqueness and are the most affected by this awareness.  Since MD5 and SHA1 are known as hash functions, these types of collisions were expected. 

What will we discuss in this article?

Most applications that utilize password storage and user rights, it's important to alter the passwords for encryption purposes.  In most cases, any medium encryption is more than enough.  In this article, we'll examine how to implement MD5 in our applications and specific means of salting the keys to add additional security.

Implementing MD5 Encryption in our Applications

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.

Add a Pinch of Salt

In the previous page, we saw an example of a simple MD5 hashing algorithm and how it's easily implemented in your web application.  The term "salt" is used to describe an addition.  Some examples available on the web will use additional strings such as username or the url of the site.  In this example, we'll use a double encryption technique, and the salt will be the outcome of the first encryption.

/// <summary>
/// Encrypts the string to a byte array using the MD5 Encryption 
/// Algorithm with an additional Salted Hash.
/// <see cref="System.Security.Cryptography.MD5CryptoServiceProvider"/>
/// </summary>
/// <param name="ToEncrypt">System.String.  Usually a password.</param>
/// <returns>System.Byte[]</returns>
public static byte[] MD5SaltedHashEncryption(string ToEncrypt) 
{
     // Create instance of the crypto provider.
     MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
     // Create a Byte array to store the encryption to return.
     byte[] hashedbytes;
     // Create a Byte array to store the salted hash.
     byte[] saltedhash;

     // let the show begin.
     hashedbytes = md5.ComputeHash(
          System.Convert.FromBase64String(ToEncrypt));

     // Let's add the salt.
     ToEncrypt += System.Convert.ToBase64String(hashedbytes);
     // Get the new byte array after adding the salt.
     saltedhash = md5.ComputeHash(textencoder.GetBytes(ToEncrypt));

     // Destroy objects that aren't needed.
     md5.Clear();
     md5 = null;

     // return the hased bytes to the calling method.
     return saltedhash;
}

In this example, we use two System.Byte arrays to store our hash outputs.  Furthermore, we use System.Convert.FromBase64 and System.Convert.ToBase64 rather than the Encoding class used in the previous example.  You may apply other spices to this method by including another string and even the start and length of the first hash to use as salt.  The more complicated you make the encryption, the harder it is to crack.

As you may have gathered, you can return a string value through the encrytion method by using the System.Convert.FromBase64 method.  In some cases, it's optimal to store a string value; however, it is optimal to use the full byte array in storage for security purposes.

The output of the salted MD5 encryption method is:

MD5SaltedHashEncryption("MyPassw0rd1sTh1s")
212, 152, 90, 70, 106, 66, 10, 5, 25, 151, 21, 164, 143, 4, 128, 218
MD5SaltedHashEncryption("myPassw0rd1sTh1s")
231, 247, 149, 128, 190, 210, 57, 167, 39, 28, 223, 164, 48, 216, 88, 24

As you can see from this example, the output is further jumbled to give the encryption a little more flavor.  To reiterate a previous point, it's best to further add to the salted scheme by adding an additional string (or more salt) to enhance the encryption further.

In Conclusion

Blast from the Past

There are many means of implementing an encryption algorithm in your applications, and MD5 is one of them.  You may implement a very straightforward, simple MD5 hashing algorithm directly from the user input, or you may choose to utilize a more complex salted approach.  Whichever type of encryption you choose to implement, it's advised to utilize a fairly strong algorithm for sensitive data such as passwords or social security numbers when decrypting the value isn't necessary.  There are times when an encrypted value must be decrypted.  Under those circumstances, alternative methods are available such as RSA, SHA1, Blowfish, Rijndael (pronounced "Rain Doll" and also known as AES), and TripleDES.  

In today's development world, Rijndael (a.k.a., AES) and TripleDES are the leaders in new development implementations, and they are both great examples of a strong balance between security and performance.  They're both private-key encryptions and have yet to be broken consistently.  It's highly recommended to avoid using anything other than Rijndael for files that have a sensitivity lifespan greater than 7 years; however, for most developers and applications, this will never be an issue.  For those interested in cryptography, it's best to further your knowledge in the different types of encryptions available: Public-Key, Private-Key, and Hashing Algorithms. 

There are many options available for cryptography purposes, and in this article, we only covered MD5 (Hashing Algorithm).  It's best to use multiple means of encryption in your applications to keep the unwanted seeker continually seeking rather than finding.

For further reading on cryptography with the .NET Framework, you may visit the following sites.

  1. http://msdn.microsoft.com/library/en-us/cpqstart/html/cpsmpnetsamples-howtocryptography.asp?frame=true
  2. http://www.gotdotnet.com/team/clr/cryptofaq.htm
  3. http://www.ftponline.com/vsm/2003_03/magazine/features/vandersypen/
  4. http://www.developer.com/net/net/article.php/1548761
  5. http://csrc.nist.gov/CryptoToolkit/aes/rijndael/
  6. http://labmice.techtarget.com/security/crypto.htm

If you have more information that you feel should be addressed in terms of cryptography or the MD5 hashing algorithm, please leave a note for discussion.  Furthermore, if you've used cryptography in the past or use it now, please let us know how it's working for you and any issues you may have run into.  There's no point in reinventing the wheel, and general discussions on the topic shouldn't sacrifice your applications security level.



©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-28 10:24:54 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search