I originally wrote this in a discussion over at the West Wind forums. I’m reposting it here for informational purposes.
MD5 can easily be reversed using a lookup of ‘known’ hashes. So if user ‘Bob’ made a choose a password of ‘abc’ and we encrypted it on the client then sent it to the server we could store it in the databases as a hash instead of plain text. Hashing something without a salt would lead to a problem when the table got stolen or a man in the middle attack occurred. The bad guy could then take the hash and look it up in the reverse table then would have Bob’s password in plain text. Salt is when you combine Bob’s password with something else. For example, create a hash of his last name, DOB, and UserId…append it to the end of the password hash his browser sent and hash them together to compare with the hashed password.
Hmm…that didn’t make a lot of sense to me…I need more Code Red. I’ll try this way:
Bob signs up for your site with user name ‘Bob’ and password ‘1234’
Password in plain text: 1234
Password hash (1234, easily reversed): 81dc9bdb52d04dc20036dbd8313ed055
Password hash with salt (1234+Bob, not as easily reversed): 27d5c234335b9762416808e2ace80842
Password hash with salt + GUID: (1234+Bob+791ae620-e2f5-11db-8314-0800200c9a66, very hard to reverse): 34e25923be3cad2bb140c8c508f59e16
Store the hash of 1234 in your table, then when it is time to compare, make sure you concatenate consistently to get the right result.
I found an MD5 program by Gilles Patrick that works really well off of the VFP Wiki. It produces results that agree with the client side JS MD5 program I linked to above.
Hashing a single word is not nearly as secure as hashing that word plus some random (but consistent) text. More and more people use the same password for their email, system, start page, etc and I think my users appreciate it when I tell them up front that I don’t know their password. Recovering a users password can be a little tricky in that they have to create a new one instead of you telling them what it is, but security questions and using the email address on file works out good for recovery.
I’m no expert on this stuff, but here are some people that are.
Very nice article. Salt is far better than md5. I appreciate the good research work by the author.
Salt is better? Salt is just adding more text to md5…it is essentially the same algorithm, just with more letters.
@stephen:
the salt makes that you cant easily take the table and do a brute force with dictionary.
i.e. if “password” was run through md5 and stored in the db,
and someone got access to the db, they can take a dictionary and run each throught the md5 function and compare it to the entries in the dB and if people have chosen weak passwords he will find matches.
by adding salt that doesnt work. of course if the guy that got a hold of the dB also knows which salt values to add, we are back to square 1….
@roadrunner: Exactly. If they can get to the source code to determine how it’s salted, then you have bigger problems.
Even if hacker got source code, he/she doesn’t aware of salt(Random or Dynamic salt) used.
example, In mailing accounts, security “question” & its “answer” can be a salt. (differ from each user:dynamic salt)
Salt(1) + Salt(2) + … + Salt(n) + MD5 = Encrypted hexadecimal output
In such cases, brutal attacks fails and encrypted text can’t be reversed.
Pingback: MD5 Hashes in Cocoa « Tom Dalling
I figured a simple way to use salt, but to also make it almost impossible to break unless you know at least how long the password was.
SUBSTRING(MD5( username + password ),MOD(LENGTH( password ), 12) +10 ) || MD5( username + password ), 0, MOD(LENGTH( password ), 12) +10 )
So basically, I do an MD5 on the combined username and password. Then, I look at the length of the password and split the resulting MD5 in two. Then i take the back half and put it at the front, thus making any lookups via rainbow table, etc. yield invalid results.
So for example, so I wanted to do it for “user” and “default”: the MD5 for “userdefault” is “4b4f5e65f81dc293b6d7a22e081e45ef”. But, since “default” is 7 characters long, then the mod calculation returns 5+10, so 15. Then the MD5 is split and reversed like so: “4b4f5e65f81dc293 b6d7a22e081e45ef” => “b6d7a22e081e45ef4b4f5e65f81dc293”
To further add a twist, you could modulus the ascii value of a designated character in the password to use for splitting (just make sure that the resulting math returns something under the 32 hex digits that make up the md5…. hence why I used mod and then added 10 so that the resulting MD5 is split SOMEWHERE close to the middle.)
how can i find the salt added to password?