I am using Blowfish with PHP crypt() for password hashing but I noticed something weird. Quoting PHP documentation:
CRYPT_BLOWFISH - Blowfish hashing with a salt as follows: "$2a$", "$2x$" or "$2y$", a two digit cost parameter, "$", and 22 digits from the alphabet "./0-9A-Za-z".
I noticed that the salt that gets included in the final hash is 1 character short (the last one is cut off) as if the salt was too long, but that is not the case.
Example of my script output:
Salt: 97504ebb48c4619f820f83 with length 22
Blowfish: $2a$13$97504ebb48c4619f820f8u4QTtlV5MoqHt9l7hmK4jEohUXrI.0PK
Hash match.
As you can see, the random salt is exactly 22 digits but the '3' is missing in the final hash. If I make the salt 21 chars only I get a corrupted hash and it does not work. So why does it trim the last char?
Examples on PHP manual also add a final $ to the random salt. Is that $ there for a reason or they just randomly added it to Blowfish, SHA-256 and SHA-512 to confuse everyone?
And finally, this is my code:
if (CRYPT_BLOWFISH == 1) {
$salt = md5(uniqid(rand(), TRUE));
$salt = substr($salt, 0, 22);
echo "Salt: " . $salt . " with length " . strlen($salt) . "<br />";
$pass = "rasmuslerdorf";
$bsalt = "$2a$13$".$salt;
$blowfish=crypt($pass, $bsalt);
echo 'Blowfish: ' . $blowfish . "<br />";
if (crypt($pass, $blowfish) == $blowfish) {
echo "Hash match.<br />";
}
else echo "no<br />";
}
else {
exit("You need php 5.3 or newer");
}