Search code examples
phpauthenticationphp-password-hash

When do I need to use password_needs_rehash()?


I have a processing file for a login to an app. I either do not understand the purpose of password_needs_rehash() or it is not working. The login is authenticating and passing me through to the correct page. But I can't get the code to even echo the new hash.

Am I doing this correctly?

Does the if not throw a new hash because it does not need rehashed? If so when would a password need rehashed if it was properly hashed and stored in the DB?

My processing file is below:

$hash = $row['hash'];
$userPassword = $_POST["li_password"];
if (password_verify($userPassword, $hash)) {
    if ( password_needs_rehash($hash, PASSWORD_DEFAULT, ['cost' => 12]) ) {
        $newhash = password_hash($userPassword, PASSWORD_DEFAULT, ['cost' => 12]);
        echo $newhash;
    }
} else {
    header('Location: http://' . $_SERVER['HTTP_HOST'] . '?error=loginfailed');
    exit();
}

Solution

  • The function password_needs_rehash() only needs to be used if you change the $options which usually refers to the cost.

    The more the cost, the more CPU time it takes to hash the password but the more difficult it becomes to crack it. If you change hosting or move over to a cloud based system where multiple computers can calculate the hash for you, you are able to increment it at your own discretion.

    You only need to check if the password needs a rehash at user login, since password_verify() can still verify the password if you changed the $options. If password_needs_rehash() returns true at that point, use password_hash() with the new options and replace the old hash.

    if (password_verify($_POST["li_password"], $row['hash'])) {
        // valid login
    
        if (password_needs_rehash($row['hash'], PASSWORD_DEFAULT, $options = ['cost' => 12])) {
            $newhash = password_hash($_POST["li_password"], PASSWORD_DEFAULT, $options);
            // store new hash in db.
        }
    } else {
        header('Location: http://' . $_SERVER['HTTP_HOST'] . '?error=loginfailed');
        exit();
    }