Estoy usando Blowfish con PHP crypt () para el hashing de contraseñas, pero noté algo extraño. Citando documentación de PHP:
CRYPT_BLOWFISH - Blowfish hashing con una sal de la siguiente manera: "$ 2a $", "$ 2x $" o "$ 2y $", un parámetro de costo de dos dígitos, "$" y 22 dígitos de el alfabeto "./0-9A-Za-z".
Noté que la sal que se incluye en el hash final es de 1 carácter corto (el último se corta) como si la sal fuera demasiado larga, pero ese no es el caso.
Ejemplo de salida de mi script:
Sal: 97504ebb48c4619f820f83 con longitud 22
Blowfish: $ 2a $ 13 $ 97504ebb48c4619f820f8u4QTtlV5MoqHt9l7hmK4jEohUXrI.0PK
Hash match.
Como puede ver, la sal aleatoria tiene exactamente 22 dígitos, pero el '3' falta en el hash final. Si hago los caracteres salt 21 solo obtengo un hash dañado y no funciona. Entonces, ¿por qué recorta el último carácter?
Los ejemplos en manual de PHP también agregan un $ final a la sal aleatoria. ¿Es ese $ por una razón o simplemente lo agregaron al azar a Blowfish, SHA-256 y SHA-512 para confundir a todos?
Y finalmente, este es mi código:
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");
}