Hashing and you

This is really simple, but don’t feel bad if you didn’t know about this. No one tells me nothin’ either.

The other day while reading through a blog, I got schooled without going to class. I had no idea that passwords should be one way only, as in you shouldn’t be able to retrieve a forgotten password, only reset it. Well shoot, I missed that one. So they start talking about hashing the password and saving that. Good thing I had built something to hash request items in a url to help stop people with screwing with a site url. Well ok, I didn’t totally build it. I got the idea from somewhere else. But I f-ing integrated it so don’t look at me like that.

Basically you take a password, add a salt (fancy name for a predetermined string or number) to the password, and get the hash value for that.

Why getting the same hash everytime sucks

Well the problem with hashing, or really the reason why we are doing this, is that the word “pass” creates the same hash value every time. Now if some sort of mean person figures out the hash for “pass” (That isn’t too hard since most people use some sort of standard like the .net MD5CryptoServiceProvider), he/she could search for a slew of typical password words. See the problem? Now enters the salt. The salt is some word that you come up with to add anywhere you want. This makes it a little difficult to figure out since the word “passSalt” is no longer like “pass”. one could try every word known and still fail because said person doesn’t know to add the word “Salt”.

Why getting the same hash everytime is great:

Right now you might be wonder what the point of having a password saved that can’t be unhashed to check against. Easy, you don’t have to unhash. Since the hash for “passSalt” will always be the same, the password in the database will always match the entered password + the salt. So basically the user enters the password, the system adds the salt to the password, the system then gets the hash, and finally checks that against the database record. Fun huh?

Now for the code:


public class HashString
{
 private const String DEFAULT_SALT = "8745";

 public static String CreateHash(String originalValue, String salt)
 {
   Byte[] computedHash;
   StringBuilder hashedValues;
   StringBuilder hashString;

   //Take the string and append your "secret" string at the end.
   hashString = new StringBuilder(originalValue);
   hashString.Append(salt);

   //Get the hash for the new word.
   computedHash = new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(hashString.ToString()));
   hashedValues = new StringBuilder();

   //Go through computedHash and create a string from it.
   computedHash.ToList().ForEach(currentItem =>
ashedValues.Append(currentItem.ToString("x2")));

   return hashedValues.ToString();
 }

 //Not needed overload, just have it here for ease of use
 public static String CreateHash(String originalValue)
 {
   return CreateHash(originalValue, DEFAULT_SALT);
 }
}

And I even have a test for you… if you have VS Professional or higher. If not, no big deal. Just remove the asserts, attributes, and step through.


[TestClass]
public class HashStringTest
{
 private class UserTable
 {
   private const String SALT_VALUE = "SomeValue";
   private List table;

   public UserTable()
   {
     table = new List();
   }

   public void AddUser(String password, String userName)
   {
     table.Add(new UserRow(){Password = HashString.CreateHash(password, SALT_VALUE), UserName = userName});
   }

   public Boolean UserExists(String password, String userName)
   {
     String hashedPassword;

     hashedPassword = HashString.CreateHash(password, SALT_VALUE);

     var query = from user in table
                 where user.Password == hashedPassword && user.UserName == userName
                 select user;

     return query.ToList().Count == 1;
   }

   private class UserRow
   {
     public String Password { get; set; }
     public String UserName { get; set; }
   }
 }

 [TestMethod]
 public void CreateHash_PasswordMatchPass()
 {
   UserTable table;
   String userName;
   String goodPassword;
   String failedPassword;

   userName = "SomeUser";
   goodPassword = "goodPassword";

   table = new UserTable();
   table.AddUser(goodPassword, userName);
   Assert.IsTrue(table.UserExists(goodPassword, userName));

   failedPassword = "failedPassword";
   Assert.IsFalse(table.UserExists(userName, failedPassword));
 }
}

And last, the namespaces:


using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using Microsoft.VisualStudio.TestTools.UnitTesting;

For the record, I hate the word salt in this use.

Random String of Specified Length with Enumerable


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public static String RandomString(Int32 length)
{
 Random randomGenerator;
 String returnValue;

  randomGenerator = new Random();

  returnValue = new string(Enumerable.Range(0, length).Select(i => (char)('A' + randomGenerator.Next(0, 25))).ToArray());

 return returnValue;
}

What this does:

Enumerable.Range basically says, “Give me a collection of numbers from the first parameter to the second”, or in this case from 0 to length.

Select basically is a method that takes in an anonymous method (Lamdba expression in this case), goes through each of the items in the collection, and runs the anonymous method for every item in the collection. Not exactly sure what Select does specifically, but it is most likely something like this: (roughish psuedo code)


public static Array Select(Func func))
{

 Array returnValue;

 foreach(Int32 currentItem in Items)
 {
    returnValue.Add(func());
 }

 return returnValue;

}

Where Func is:


public Char Func()
{
 return  (char)('A' + randomGenerator.Next(0, 25);
}

Random Enumeration Generator with Generics


public static I RandomEnumeration<I>()
{
  I enumerationToCheck;
  Int32 indexToUse;
  String[] names;

  //Use activator to create an instance of the type I
  enumerationToCheck = System.Activator.CreateInstance<I>();

  //Make sure the instance is an Enumeration
   //Unfortunately you can't check that in the method 
   //delcaring using "which".
  if (enumerationToCheck as Enum == null)
  {
    throw new InvalidOperationException();
  }

  //Get the list of the enumeration item names
  names = Enum.GetNames(typeof(I));

  if (names.Length > 0)
  {
    //Grab a random name within the boundaries of the
     //names collection.
    indexToUse = RandomInt32(0, names.Length);
    //parse the name to create the random enum
    enumerationToCheck = (I)Enum.Parse(typeof(I), names[indexToUse]);
  }

  return enumerationToCheck;

}

Usage:


  SomeEnum test = RandomEnumeration();

Why bother? For unit testing and creating test classes. Possibly
for defaults on an enumeration, but not really needed since
they are value types. Oh yeah AND BECAUSE I FELT LIKE IT. I don’t
have to explain myself to you.