Okay. So if it's impossible to determine the ASCII value, what makes it such an unsafe method of comparing passwords?
In some of my old PHP scripts, I commonly had MD5()'s of passwords stored in a MySQL db, and used that as a comparison for people logging in.
I'd often do something like:
$md5Password = MD5($username . $password)
Or even perhaps a few MD5's, or toss in some arbitrary text.
$md5Password = MD5('passEncrypt' . MD5($username) . $password)
Then when I wanted to log that user in it was a simple method of comparing:
If MD5($username . $password) == $md5Password) {}
Is that really all that insecure?
<{POST_SNAPBACK}>
It is NOT an unsafe method of comparing passwords. All most all good authentication is performed in this manner.
Because MD5 is a hash checksum. That means that multiple ASCII strings can have the same checksum. So you just have to calculate AN ASCII string that produces the same hash.
See also: http://userpages.umbc.edu/~mabzug1/cs/md5/md5.html
and http://www.rtfm.com/movabletype/archives/2004_08.html#001055 for an example of two different input vectors that produce the same MD5 checksum.
Regards,
-Sven
<{POST_SNAPBACK}>
Two inputs of differing content CANNOT produce the same hash.* That goes against the whole purpose of calculating checksums/hashes. Hashing algorithms are specifically designed to produce a predictable hash based on input. And that said input cannot be produced from the hash. It's a one-way street.
The only way to crack a hash is as follows:
You have a hash like this: 5f4dcc3b5aa765d61d8327deb882cf99. You want to find out what input created that hash. To do so you would have to loop through every possible combination of characters, generating the hash for each one, and comparing your generated hash with the hash you were given that the outset. This can be done a variety of ways. Some are:
Dictionary Attack: You have a long list of words and letter combinations that are commonly used as passwords. You loop through the list and generate a hash for each word, and compare with the one given. Success is not guaranteed.
Brute Force Attack: You loop through every single possible combination of characters in a specified character set, generating hashes for each one, and comparing it with the given hash. The wider the character set the longer it takes. The stronger the password, the longer it takes, If you don't include every single character in your character set, success is not guaranteed. As the length and complexity of the password increase the time required to crack it increases exponentially. Some passwords cannot be cracked this way because it would take hundreds or thousands of years.
Rainbow Tables: This is one of the newest and fastest ways to crack passwords. You have a long list of recomputed hashes and their values (a table). You loop through each hash and compare it with the one given. This method can only be used to crack passwords less than 15 characters. Success is not guaranteed if your tables are not big enough.
All of the above mentioned methods are very resource intensive. The probability of a password being cracked rests, not on the strength of the hash (MD5), but on the strength of the password. I hope this clears things up for you just a little.
* Over time people have sometimes found slight flaws in algorithms. These flaws might cause an identical checksum to be produced from varying input. BUT THIS IS ONLY IN EXTREME CASES. IT DOES NOT MAKE IT INSECURE!
Edited by Green_Lantern, 26 April 2005 - 01:05 PM.