Encryption 101: This Hash Needs Salt

Yesterday, I wrote about how to do simple, one-way encryption using a hash algorithm. This is terrific for encrypting data that doesn’t need to be decrypted, like user passwords. The problem with hash algorithms is that the same values encrypt to the same encrypted values. This is bad because it is possible to see that two encrypted values are the same.

But do not worry. You can turn a hash into a salted hash with one very easy adjustment: add some random bytes to the value. Of course, in order for this to be effective, you’ll also need to store the salt value. When creating the hash for storage, you’ll use salt+value. When creating the hash for comparison, you’ll use salt+value. Get it?

Here’s a short example that uses the RNGCryptoServiceProvider class (RNG = Random Number Generator) to create a salt:

namespace adamprescott.net.EncryptionSaltedHash
{
    using System;
    using System.Security.Cryptography;
    using System.Text;

    class Program
    {
        static void Main(string[] args)
        {
            var p = new Program();
            p.Run();
        }

        private void Run()
        {
            Console.Write("Input: ");
            var input = Console.ReadLine();

            var salt = GetSalt();
            var hashed = HashText(salt + input);
            Console.WriteLine("Salt: {0}", salt);
            Console.WriteLine("Hashed: {0}", HashText(input));

            Console.WriteLine();
            Console.Write("What did you just enter?: ");
            input = Console.ReadLine();
            if (string.Equals(hashed, HashText(salt + input)))
            {
                Console.WriteLine("You are an honest person.");
            }
            else
            {
                Console.WriteLine("You are a liar!");
            }

            Console.ReadLine();
        }

        private string HashText(string text)
        {
            using (var md5 = new MD5CryptoServiceProvider())
            {
                var bytes = Encoding.UTF8.GetBytes(text);
                var hash = md5.ComputeHash(bytes);
                return Convert.ToBase64String(hash);
            }
        }

        private string GetSalt()
        {
            using (var rng = new RNGCryptoServiceProvider())
            {
                var bytes = new byte[8];
                rng.GetBytes(bytes);
                return Convert.ToBase64String(bytes);
            }
        }
    }
}
Advertisements

One thought on “Encryption 101: This Hash Needs Salt”

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s