I was wondering if it was possible/wise to use password_hash twice for my users passwords on my website.
So let's say this:
User registers on my site, they enter a password, we will call this input
.
During account creation, their password is $firstHash = password_hash($input, PASSWORD_BCRYPT)
(For example sake, lets say this hashes to "thisFirstHash"
Once their password is hashed, it is hashed again $firstHash = password_hash($firstHash, PASSWORD_BCRYPT)
(For example sake, lets say this hashes to "thisSecondHash")
This second hash is what is stored to the database, so now when they log in, the server has to decrypt a hashed hash.
When the user logs in, they enter their password again, we will again call this input
the server then has to reencrypt the input to compare with the saved hash $loginHash1 = password_hash($input, PASSWORD_BCRYPT)
The server compares the new loginHash1
variable with the saved hash password_verify($loginHash1,"thisSecondHash")
If the first hash matches, compare the second hash
password_verify($input,"thisFirstHash")
I couldn't quite get this to work properly in my small testing environment, I suspect it has something to do with the randomized salt being different during the login phase when rehashing the input.
So my questions are,
The whole point of the password hashing API is to make it simple to implement secure hashing. Adding complexity as you are will not add any security, and it makes your code more difficult to debug. Use one password_hash
and one password_verify
. PHP's PASSWORD_DEFAULT
is chosen to be very strong already:
To hash
$hash = password_hash($cleartext, PASSWORD_DEFAULT)
To verify
$isCorrect = password_verify($cleartext, $hash);
If you're not happy with PHP's very strong defaults, you can look into the cost
setting. But it's really not needed. The docs say:
password_hash() uses a strong hash, generates a strong salt, and applies proper rounds automatically. password_hash() is a simple crypt() wrapper and compatible with existing password hashes. Use of password_hash() is encouraged.
The password_hash()
function already does repeatedly hash the password, this is called key-stretching and is done to make brute-force attacks more difficult. So there is no point in using BCrypt twice.
The reason why it doesn't work in your case, is because password_hash() adds a random salt which becomes part of the resulting hash. This salt is necessary to verify the password, but with calling the function twice you loose the first salt.