So I'm using the new PHP 5.5 Password Hashing API, and I'm not sure if I got this correctly.
I've tried automatically rehashing every login and sometimes I fail, even when the hashing turns out to be the same anyways, I feel like I'm doing something wrong.
It could be the query function that I probably got wrong, because the hashes don't even change when I check phpMyAdmin.
if (password_needs_rehash($result_row->user_password_hash, PASSWORD_DEFAULT))
{
$newhash = password_hash(
$_POST['user_password'], PASSWORD_BCRYPT,
['cost' => 12, 'salt' => 'superfreakingsonicdude',]
);
// update hash in database
$this->connection->query(
"UPDATE users SET user_password_hash='" . $newhash .
"' WHERE user_name='".$result_row->user_name."'"
);
}
Here is where you can find all the functions.
SHA-256 is one of the most secure hashing functions on the market. The US government requires its agencies to protect certain sensitive information using SHA-256.
You will need to verify the user passwords to see if they match the passwords stored in the database. To do this, we call check() on the Hash façade. The check() method verifies if the plain-text string entered by the user matches the given hash. The code above uses the Hash facade alongside the check() method.
To protect passwords, experts suggest using a strong and slow hashing algorithm like Argon2 or Bcrypt, combined with salt (or even better, with salt and pepper). (Basically, avoid faster algorithms for this usage.) To verify file signatures and certificates, SHA-256 is among your best hashing algorithm choices.
Hashed passwords cannot be retrieved in general (this depends on the hashing function, secure hashes cannot be retrieved). If they have the same hash on two sites, they could have the same password, this depends on the hash salt used by the sites, what method etc.
The funcion password_needs_rehash
has been introduced to check if you need to upgrade:
password_needs_rehash($result_row->user_password_hash, PASSWORD_DEFAULT)
This function checks to see if the supplied hash implements the algorithm and options provided. If not, it is assumed that the hash needs to be rehashed.
If you have problems to understand what this function does, the RFC contains the function in PHP code. So if you can read PHP code, you should be able to read the following (see the part introduced as It could be implemented in user-land by:): https://wiki.php.net/rfc/password_hash#password_needs_rehash
Makes sense to test if the hash in the database (store) is of the same algorithm as in PASSWORD_DEFAULT
or not. That means to check if PASSWORD_DEFAULT
has been changed between the time the hash has been stored last time and now.
Right now PASSWORD_DEFAULT
is PASSWORD_BCRYPT
so it should always return false. In your case it returns true, because you're testing without your password options.
Change that and you should be fine:
$options = ['cost' => 12, 'salt' => 'superfreakingsonicdude',];
########
if (password_needs_rehash($result_row->user_password_hash, PASSWORD_DEFAULT, $options))
########
{
$newhash = password_hash($_POST['user_password'], PASSWORD_DEFAULT, $options);
################ ########
// update hash in database
$this->connection->query(
"UPDATE users SET user_password_hash='" . $newhash .
"' WHERE user_name='".$result_row->user_name."'"
);
}
Also consider to continue to use PASSWORD_DEFAULT
if you want to benefit from a default hashing algo update in PHP core.
The input to the hash is the password and salt. Same password, same salt, same result.
If you leave the salt
parameter out, a random salt will be generated each time and you should get a different result. You should not provide a static salt. This means all users have the same salt, which greatly diminishes its effectiveness. Each individual hash needs should have a random salt.
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