How to Use password_needs_rehash in PHP

Keeping user passwords secure requires updating their hashes when your application’s security standards, algorithms, or configuration options change. This article explains how to use PHP’s built-in password_needs_rehash() function to detect when a stored password hash is outdated and how to seamlessly update it during the login process without disrupting the user experience.

Why Use password_needs_rehash()?

As computing power increases, older hashing configurations (like a low cost factor in BCRYPT) become vulnerable to brute-force attacks. Additionally, you may want to upgrade your hashing algorithm entirely—for example, switching from PASSWORD_BCRYPT to PASSWORD_ARGON2ID.

Because you cannot decrypt existing password hashes to re-encrypt them with new settings, you must perform this update when the user logs in and provides their plain-text password. The password_needs_rehash() function checks if a stored hash was created using a specific algorithm and option set. If it was not, the function returns true, signaling that you need to rehash the password and update the database.

The Verification and Rehash Workflow

To implement this, you check the password status immediately after successfully verifying the user’s credentials.

Here is a practical code example demonstrating this workflow:

// 1. Define your current, ideal security configuration
$currentAlgorithm = PASSWORD_DEFAULT;
$currentOptions = [
    'cost' => 12 // Increased from the default of 10
];

$userInputPassword = $_POST['password'];
$userEmail = $_POST['email'];

// 2. Fetch the user's record from the database
$user = getUserByEmail($userEmail); // Hypothesis helper function

if ($user && password_verify($userInputPassword, $user['password_hash'])) {
    // The password is correct, log the user in.
    
    // 3. Check if the hash matches the current security configuration
    if (password_needs_rehash($user['password_hash'], $currentAlgorithm, $currentOptions)) {
        
        // 4. Generate a new hash using the plain-text password provided during login
        $newHash = password_hash($userInputPassword, $currentAlgorithm, $currentOptions);
        
        // 5. Update the database with the new hash
        updateUserPasswordHash($user['id'], $newHash); // Hypothesis helper function
    }
    
    // Proceed with starting the user session
    echo "Login successful!";
} else {
    echo "Invalid credentials.";
}

How the Parameters Work

The password_needs_rehash() function accepts three arguments:

  1. $hash: The existing hash currently stored in your database.
  2. $algo: The password algorithm constant you want to enforce (e.g., PASSWORD_DEFAULT, PASSWORD_BCRYPT, or PASSWORD_ARGON2ID).
  3. $options: An associative array containing the settings (like cost, memory_cost, or time_cost) you want to enforce.

If the provided $hash was created using a different algorithm or different options than those specified in the second and third arguments, the function returns true. Otherwise, it returns false, meaning no action is required.