Using md5 on a string always produces an alpha-numeric encrypted result, ie: no symbols.
However, when I using the php crypt() function, specifically the CRYPT_MD5 (and it is on, I've checked) with a salt, the supposed md5 hash it returns does not look like an md5 hash.
For example:
if I md5 the string 'password', I get:
$pass = md5('password');
echo $pass;
//5f4dcc3b5aa765d61d8327deb882cf99
if I use CRYPT_MD5, which is denoted by the '$1$' prefix and the '$' suffix with the salt being 'salt':
$pass = crypt('password', '$1$salt$');
echo $pass;
//$1$salt$qJH7.N4xYta3aEG/dfqo/0
Now, the algorithm and salt used are shown as expected, '$1$' shows that the CRYPT_MD5 was used and the salt is shown to be 'salt' as between the $ signs.
However.. the hashed password after that last $ sign does not look like an md5... it has slashes and full-stops in it.
Why does it hash it this way? Is this not a real md5?
Please ask if you need me to clarify any of this. Ugh.
- MD5 is a hashing algorithm not encryption.
- The output of MD5 is 128 bits of data. Your first example is encoding the 128 bits as 32 Hexadecimal digits (4-bits per digit). The second example is in the crypt alphabet ./0-9A-Za-z - 21 chars at 6 bits per char.
For more details on the crypt algorithm see http://www.gnu.org/software/libtool/manual/libc/crypt.html
You are correct, 5f4dcc3b5aa765d61d8327deb882cf99 is the MD5 of the string "password". It has no salt added, but you could easily add one by taking MD5("password" . "$salt")
However, the PHP crypt() function can use a variety of different hashes to compute the hash. When you prefix your salt with "$1$" you get a hash with an MD5. When you prefix with $2$ you get a crypt with blowfish, which is more secure.
The "$1$" is prefixed to the output so that the hash can be verified. If it wasn't included, there would be no way to know from the stored hash which algorithm should be used! This information would have to be stored elsewhere. To save you this trouble PHP includes the algorithm in the hash output.
So to verify a hash, you take the password provided by the user as the password, and you take everything up to the third dollarsign as the salt, and you see if the results you get match the results that are stored.
The next part of your confusion is that the MD5() function is giving you a hex hash, whereas the crypt() function is giving you a hash coded in Base64. That's because Base64 is more efficient.
Simple?
It is a MD5 hash, just not properly formatted as a string. Shouldn't give you a problem.
These are my thoughts - not sure if correct.
md5 calculates a hash whereas crypt performs encryption - albeit using an md5 flavour.
Hashes are 1-way, and give fixed length results for arbitrary length input.
Encryption is 2-way and doesn't give fixed length results.
My guess is that the md5 hash rfc probably defines the result to use [a-z],[A-Z],[0-9] whereas encryption has no such limitation.