Password Security with Hashing Functions - Security Series #4.2

This week I want to look at password hashing and salting. This is a topic that many people have a hard time grokking, but it is essential to proper password security. We'll take this slow, I think. First we'll discuss hashing, then salting, then storing. The overall point of these posts are to get across the use of hashing and salting to protect the passwords on your system. This is going to be a fairly long series. I am about halfway done writing it at he time of this posting, and I am at 1000 words. So I will be releasing it in pieces throughout this week, and probably next week.

Salting and Hashing passwords is a method of securing passwords through obfuscation and "one-way encryption". This methodology of password protection is becoming more common, but hashing them only, or worse, storing passwords in clear text, are still far too prevelent.

What is hashing?

From Wikipedia: "... a Cryptographic Hash Function is a transformation that takes an input and returns a fixed-size string, which is called the hash value.

The Hash value (or digest) that is returned from the hash function should be very difficult (bordering on impossible) to reverse back to its original form, and the hash value should be unique. A secure hash cannot be "unhashed" and there should not be collision between hashes, where two input values would produce the same hash. To learn more about hashing, check out the Wikipedia Article or consult your local crypto/math expert who will talk your ear off about the subject.

To avoid confusion, and at the risk of being corrected by a smarty-pant, I will simplify and say that a hash function takes an input string, scrambles it up in a predictable manner and returns another string that cannot be reversed.

Let's look at some code.
If I take the following three values:

<cfset val1 = "Jason" />
<cfset val2 = "Model-Glue" />
<cfset val3 = "SR-71 Blackbird" />

and hash them using the popular MD5 hash function

<cfset hash1 = Hash(val1,"MD5") />
<cfset hash2 = Hash(val2,"MD5") />
<cfset hash3 = Hash(val3,"MD5") />

And output them to the screen

<cfoutput>
#hash1#<br />
#hash2#<br />
#hash3#<br />
</cfoutput>
    

I would get these values:
472D46CB829018F9DBD65FB8479A49BB
2429B9A443D9C21B0698ADBE2F6E01C0
10F1C46CAF873486E530570E7A298BBB

So regardless of the length of the input string, the results are all the same length, but with unique values.

Now, let's do that same hash again:

472D46CB829018F9DBD65FB8479A49BB
2429B9A443D9C21B0698ADBE2F6E01C0
10F1C46CAF873486E530570E7A298BBB

Oh, look at that, the exact same values. This is what I meant by "predictable" results. If you hash a string of text with the same hash function over and over again, you will always get the same result. That presents an issue that we will talk about when we discuss salting.

I mentioned MD5 before because it is very popular and has been in use for a long time. However MD5 is not secure, DO NOT use it for your password hashing. MD5 has security vulnerabilites which include weak collision resistance and the existence of numerous Rainbow Table projects which can be used to crack MD5 hashed password in a matter of minutes.

So our first step in securing our users' passwords is to Hash the password using a good hashing function like SHA-256 or SHA-512. So that our hash is virtually impossible to reverse and so there will be no collision of hash values.

But wait, if hashes are irreversible, how can I send my users their passwords when they click on the "Forgot my password" link?

That's a very good question, and the answer is, you don't. What you do instead, is generate a random password (7 or 8 characters ought to do) and you Hash that and then send the new unhashed password to your user. The new password you send should be for one-time use only and should expire after a short time. Another option that many employ is to send the user a one-time unique, time-sensitive URL that they can click on and then reset the password themselves. Either method, I think, is acceptable.

So the next question you might have is: "Now wait just a second Jason, if these Hashes are so 'predictable', then I could just keep a spreadsheet with all of these hashed values of common passwords and use that to compare against a compromised database table of hashed password! Right"

If you asked that question, then Kudos! Bravo Zulu, to you. That is the exact right question ask. You should become a security professional. What you are describing there, in essence, is a rainbow table. A rainbow table is a look up table of possible hash values for common passwords, credit card numbers, or any other data that could be obfuscated through hashing. The existence of rainbow tables adds another step to our password security. Fortunately, it is an easy step. It is called "salting".

We will discuss salting passwords in my next post, due out later this week.

Comments
Ben Nadel's Gravatar

Just so I am clear on Hashing, it is possible for two strings to result in the same hash value, right?



Also, if a hash value is 32 characters long, and the value you are hashing is greater than 32 characters long, does that make it any harder to "crack"?



Looking forward to next part.

# Posted By Ben Nadel | 5/19/08 6:38 AM
Jason Dean's Gravatar

@Ben



The answer to the first part was getting too long, soI made a new entry for it. You can find it here, http://www.12robots.com/index.cfm?event=showEntry&...



Or if that link doesn;t work, then it is entry 4.2.1 of the security series.



I am hoping the post also answers your second question, since in most cases we will not be using the 32 character MD5 hash.

# Posted By Jason Dean | 5/19/08 9:18 AM
BlogCFC was created by Raymond Camden. This blog is running version 5.9.1. Contact Blog Owner