He estado usando PHP crypt()
como una forma de almacenar y verificar contraseñas en mi base de datos. Utilizo hashing para otras cosas, pero crypt()
para contraseñas. La documentación no es tan buena y parece que hay mucho debate. Estoy usando blowfish y dos sales para cifrar una contraseña y almacenarla en la base de datos. Antes almacenaba la sal y la contraseña cifrada (como un hash salado) pero me di cuenta de que era redundante porque el salt formaba parte de la cadena de contraseña cifrada.¿Estoy usando correctamente la función crypt() de PHP?
Estoy un poco confundido sobre cómo funcionarían los ataques de tabla de arco iris en crypt()
, de todos modos, esto parece correcto desde un punto de vista de seguridad. Uso una segunda sal para agregar a la contraseña para aumentar la entropía de las contraseñas cortas, probablemente exagerada, pero ¿por qué no?
function crypt_password($password) {
if ($password) {
//find the longest valid salt allowed by server
$max_salt = CRYPT_SALT_LENGTH;
//blowfish hashing with a salt as follows: "$2a$", a two digit cost parameter, "$", and 22 base 64
$blowfish = '$2a$10$';
//get the longest salt, could set to 22 crypt ignores extra data
$salt = get_salt ($max_salt);
//get a second salt to strengthen password
$salt2 = get_salt (30); //set to whatever
//append salt2 data to the password, and crypt using salt, results in a 60 char output
$crypt_pass = crypt ($password . $salt2, $blowfish . $salt);
//insert crypt pass along with salt2 into database.
$sql = "insert into database....";
return true;
}
}
function get_salt($length) {
$options = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./';
$salt = '';
for($i = 0; $i <= $length; $i ++) {
$options = str_shuffle ($options);
$salt .= $options [rand (0, 63)];
}
return $salt;
}
function verify_password($input_password)
{
if($input_password)
{
//get stored crypt pass,and salt2 from the database
$stored_password = 'somethingfromdatabase';
$stored_salt2 = 'somethingelsefromdatabase';
//compare the crypt of input+stored_salt2 to the stored crypt password
if (crypt($input_password . $stored_salt2, $stored_password) == $stored_password) {
//authenticated
return true;
}
else return false;
}
else return false;
}
Usar 'mt_rand' en lugar de' rand' sería una pequeña mejora de su script – Sliq