So I was looking at WordPress'es source because I was curious how hashes are compared on the back-end. However, I am at a loss to understand how exactly phpass is meant to produce different hashes for a single input (considering a different, random salt every time).
As in the latest WordPress version, the CMS uses the CheckPassword function as defined:
function CheckPassword($password, $stored_hash)
{
if ( strlen( $password ) > 4096 ) {
return false;
}
$hash = $this->crypt_private($password, $stored_hash);
if ($hash[0] == '*')
$hash = crypt($password, $stored_hash);
return $hash === $stored_hash;
}
Shouldn't hash
have a different value all the time, regardless of the input due to the salt? Is WordPress using a static salt for hashes? If so, where is it defined and how is it being generated?
So I was looking at WordPress'es source because I was curious how hashes are compared on the back-end. However, I am at a loss to understand how exactly phpass is meant to produce different hashes for a single input (considering a different, random salt every time).
As in the latest WordPress version, the CMS uses the CheckPassword function as defined:
function CheckPassword($password, $stored_hash)
{
if ( strlen( $password ) > 4096 ) {
return false;
}
$hash = $this->crypt_private($password, $stored_hash);
if ($hash[0] == '*')
$hash = crypt($password, $stored_hash);
return $hash === $stored_hash;
}
Shouldn't hash
have a different value all the time, regardless of the input due to the salt? Is WordPress using a static salt for hashes? If so, where is it defined and how is it being generated?
The point of hashing a password when storing it in the DB is that it will not be disclosed if anyone got a dump of the DB. There has to be a 1:1 relationship between the password and the hash here as you need to be able to compute the hash of a given password and verify its correctness against the value stored in the DB, something you will not be able to do if there might have been more than one correct result for hashing a password.
Using salts will not make any real difference, as any salt you will add will be constant and added in the same way and there will still be a 1:1 relationship between the password and the value stored in the DB.
The other factor that is actually highlighted when looking at how verify_password
works, is that hashes many times contain signature which indicates what type of hash was used to generate them so the software can be able to use the correct hashing when comparing the values. A not careful manipulation of that value is risking that you will not be able to know which hash to use.
Last and not least is the fact that salts are configurable by the user (in wp-config.php
) and if you will use a salt when hashing a password, you risk users not being able to ever login again without resetting their passwords, if a salt changes. OTOH if you hardcoded the value in the code, than since it is open source everybody can know the salt which is being used which will make the whole thing pointless.
People that feel like the way wordpress handles hashing is not secure enough for their requirement can always implement their own algorithms and override the wordpress ones.
password_verify
works either. It's not possible to test if a value is correct without it being a 1:1 match without being able to undo the hashing, and the whole point of hashing is that it's near impossible to undo – Tom J Nowell ♦ Commented Oct 29, 2018 at 15:17