Saturday 14 January 2012

C# - How to make an MD5 hash of a string

Problem

Ok, so you're building an application that uses some kind of authentication for its users and you need to store their passwords. Are you going to just shove them in your database in plain text? Would you be happy if the various sites you use did that with your sensative data? I didn't think so, buddy.

Solution

We'd better apply some kind of hashing to things like passwords, to make sure that if somehow Lord Haxer the third breaks into your database, they will have a tougher time decrypting what they find. MD5 is one of the most common hashing solutions and this is why I've given it. Please see the notes below, though.

Well, this is more of a reblog than something I found on my own, but I can definitely verify its usefulness. Taken from the C# FAQ blog and posted by Jani Järvinen and can be found at http://blogs.msdn.com/b/csharpfaq/archive/2006/10/09/how-do-i-calculate-a-md5-hash-from-a-string_3f00_.aspx. If you're here for the code, here it is. Please note I've shortened the code slightly by use of a using statement for the Crypto library and System.Text, which are both used here.

using System.Security.Cryptography;
using System.Text; // used for encoding

public string CalculateMD5Hash(string input)
{
// step 1, calculate MD5 hash from input
MD5 md5 = MD5.Create();
byte[] inputBytes = Encoding.ASCII.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}

Thanks to the original author and I hope you all find that useful.

Notes on MD5

Please note, MD5 isn't by any means a guarantee of security. Far from it, it has been cracked and there are several tools to do it. Yeah, we've all done it. But it is better than nothing and it is a start. However, for better guarantees of security, try SHA1 or SHA256, when I've had cause to come across something to do that, I will be sure to post. I do not recommend MD5 for anything where data is hugely sensative. It is, however, easy and smaller.

Salting

A later edit, thanks to a reader who pointed this out, salting is often a very useful technique to employ alongside this. It will foil some rainbow table and dictionary attacks on the hashes, as well as slowing down brute force attacks. In its simplest form, you could prepend or append a static string to all passed in passwords. However, this suffers with the issue that as soon as your salt is cracked, it's as good as game over. What is more typically done is a random (or possibly little known) character set is used, possibly taken from the user account itself. An example may be to use the day of the month the user registered within the salted string, thereby making the hashes much more resistant.

Here's a quick and easy adaptation of the code above, with salting implemented.

public string CalculateMD5Hash(string input, string dayJoined)
{
// step 1, calculate MD5 hash from input
string _saltedInput = "YouJoinedOnDay" + dayJoined + "." + input;
MD5 md5 = MD5.Create();
byte[] inputBytes = Encoding.ASCII.GetBytes(_saltedInput);
....

The above is just sample code, so it's not been tested, but I hope it gives you the idea.

Go easy on the hash!

No comments:

Post a Comment

As always, feel free to leave a comment.