PHP Password Hashing

PHP Password Hashing

Storing plain-text passwords is a critical security mistake. PHP's password_hash() and password_verify() use bcrypt by default — the right tools for the job.

1 - Hashing

$plain = "mySecretPass123!";

// PASSWORD_DEFAULT = bcrypt (currently)
$hash = password_hash($plain, PASSWORD_DEFAULT);

// Bcrypt with cost factor (default is 10)
$hash = password_hash($plain, PASSWORD_BCRYPT, ["cost" => 12]);

2 - Verifying

$plain = $_POST["password"];
// $hash comes from the database

if (password_verify($plain, $hash)) {
    // Correct password — start session
    session_start();
    session_regenerate_id(true);
    $_SESSION["user_id"] = $user["id"];
} else {
    echo "Invalid credentials.";
}

3 - Rehashing on Login

if (password_needs_rehash($hash, PASSWORD_DEFAULT, ["cost" => 12])) {
    $newHash = password_hash($plain, PASSWORD_DEFAULT, ["cost" => 12]);
    // UPDATE users SET password = ? WHERE id = ?
}

4 - Argon2id (PHP 7.3+, recommended)

$hash = password_hash($plain, PASSWORD_ARGON2ID, [
    "memory_cost" => 65536, // 64 MB
    "time_cost"   => 4,
    "threads"     => 3,
]);

Note: Never use md5(), sha1(), or sha256() for passwords — they are fast hashing algorithms, trivially reversed with rainbow tables. password_hash() is slow by design.

-Tip-