After some troubleshooting, I have determined that when I hash a password using PHP's password_hash function, the encryption identifier is $2y$. However, when I use the password_verify function to compare the stored hashed password with the user input password, password_verify will not return true. If I generate a new password using the $2a$ identifier on https://www.bcrypt-generator.com/ and replace the stored hashed password with it, it returns true.
I'm hoping someone can explain why password_hash($password, PASSWORD_DEFAULT) is using $2y$ and why password_verify() is using $2a$. Or anything else I might be doing wrong here for that matter. I am doing this locally on WAMP Server running PHP Version 7.0.10.
Here is an example of the code I am having trouble with ($2y$ identifier will not return true).
<?php
// $hashNotWorking came from password_hash("testing", PASSWORD_DEFAULT)."\n";
$hashNotWorking = '$2y$10$DNPos6f7Vo4Z2IrYU./eCObD7BMkwlkK9yiYjb0hvnI14B1dbFHbC';
if (password_verify('testing', $hashNotWorking)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
?>
Here is an example of the code that is working ($2a$ encryption NOT generated by password_hash function).
<?php
// $hashWorking came from https://www.bcrypt-generator.com/
$hashWorking = '$2a$08$uP75n/pDhUZo6qOOM3DuPug5U2fcSXW4f3MUz8p3SlO5yPZ4fLf9O';
if (password_verify('testing', $hashWorking)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
?>
password_hash is designed to generate a random salt every time. This means you have to break each hash individually instead of guessing one salt used for everything and having a huge leg up.
The result hash from password_hash() is secure because: It uses a strong hashing algorithm. It adds a random salt to prevent rainbow tables and dictionary attacks.
The password_verify() function is used to match the hash password with the original password. Another function, password_hash() is used to generate the hash value based on the hashing algorithm, cost, and salt value. The password_verify() function contains all hashing information to verify the hash with the password.
The password_verify() function can verify that given hash matches the given password. Note that the password_hash() function can return the algorithm, cost, and salt as part of a returned hash. Therefore, all information that needs to verify a hash that includes in it.
I suspect that there might have been whitespace introduced in the original hash and/or a <br>
, or that some may have been introduced by the user.
I have seen cases like this often before.
If that is the case, trim()
it.
Create a new hash as per what I mentioned in comments and it will work.
echo $var = password_hash("testing", PASSWORD_DEFAULT)."\n";
Then paste it in place of what your present hash is.
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