This is my first time using the crypt() function in PHP, and I can't figure out why it isn't working. My code is based on this article: http://www.techrepublic.com/blog/australia/securing-passwords-with-blowfish/1274
function blowfishHash ($pw) {
//generate random salt
$salt = "$2y$10$";
for ($i = 0; $i < 22; $i++) {
$salt .= substr("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", mt_rand(0, 63), 1);
}
$hash = crypt($pw, $salt);
//printout to file
$file = fopen("debug.txt", "w+");
fwrite($file, "\n\n\n".$pw);
fwrite($file, "\n\n\n".$salt);
fwrite($file, "\n\n\n".$hash);
fclose($file);
return $hash;
}
I called the function with the sample password "password".
The resultant salt was: $2y$10$NzRQNjTRfP4jXKvb4TCO.G
But the password was "$2mV0NZp92R3g"
– which seems far too short.
Could someone please help me figure out what I'm doing wrong?
As you stated in your comment, you are using PHP 5.2.x.
The Blowfish implementation is only available in PHP >= 5.3.x. If for any reason it is not possible to install a newer PHP version, you could check here on more information on how to make Blowfish work with older PHP versions.
Since crypt
in PHP 5.2 doesn't support CRYPT_BLOWFISH, it is instead defaulting to interpreting the salt as a CRYPT_DES style salt. Notice that the output starts with "$2", which is the two character salt that CRYPT_DES chose from the salt input and prepended to the hash, and the output length matches the exact CRYPT_DES output length.
Interestingly, you can achieve the same result in later PHP versions with CRYPT_BLOWFISH support by simply truncating the salt to two characters. Ie:
crypt('password', '$2y$10$NzRQNjTRfP4jXKvb4TCO.G') /* in PHP 5.2 */
==
crypt('password', '$2') /* in PHP 5.4 */
In theory, this might come in handy for backwards-compatibility if a CRYPT_BLOWFISH style salt was used in error on PHP 5.2.
This actually caused me a bit of confusion recently because the "$" character isn't valid salt input for CRYPT_DES as per the PHP crypt documentation, which says:
Standard DES-based hash with a two character salt from the alphabet "./0-9A-Za-z". Using invalid characters in the salt will cause crypt() to fail.
But here the "$" character clearly seems to be accepted by crypt()
in both v5.2 and v5.4.
It would be both clearer and safer if crypt
actually returned a failure like the documentation says it's supposed to, rather than accepting the "$" and defaulting to CRYPT_DES.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With