I have a register page that allow user to insert password so i need to hash it to become more secure in the database this work fine
but when it come to the login t
Upon registration you create a unique salt. That salt is now part of the hash. If you look closely, you'll see it's embedded in the first part of the hash. To check the password, use the previous hashed password's salt, so you're using the same salt again.
$correctPasswordHash = getPasswordFromDatabase($_POST['username']);
$hash = crypt($_POST['password'], $correctPasswordHash);
if ($correctPasswordHash === $hash) ...
To make this easier and more foolproof, use the password_compat library, which wraps this in an easy to use API, which will also be integrated into a future version of PHP. Inspect its source code for the correct usage of crypt
, since there are some pitfalls you need to take care of. The password_compat library is also using a custom binary comparison instead of a simple ===
to thwart timing attacks.
If I understand your code correctly, the login-time code is generating a fresh salt, ignoring the one that's stored with the password. Using different salts to hash the same password will generate different hashes.
Either use a constant salt pepper (scroll to the bottom of this answer), as per @c2's answer:
function cryptPass($input, $rounds = 9)
{
return crypt($input, sprintf('$2y$%02d$mysalt$', $rounds));
}
$hash = cryptPass($pass);
Or use the same salt both times:
// Login time (register-time code is unchanged)
function cryptPass($input, $salt, $rounds = 9)
{
return crypt($input, sprintf('$2y$%02d$%s$', $rounds, $salt));
}
function checkPass($freshPass, $hashFromDatabase) {
$salt = explode('$', $hashfromDatabase, 5);
$salt = $salt[3];
return cryptPass($freshPass, $salt) === $hashFromDatabase;
}