Secure PHP Password Storage: md5, password_hash, and crypt Explained with Code

This guide walks through three common PHP password‑hashing techniques—md5, password_hash (BCrypt), and crypt—showing complete registration and login code samples, highlighting security drawbacks of md5 and recommending stronger, salted hashing for safe user authentication.

php Courses
php Courses
php Courses
Secure PHP Password Storage: md5, password_hash, and crypt Explained with Code

Password Hashing in PHP

1. Using md5 (insecure)

The md5 function produces a 32‑character hash but does not use a salt and is vulnerable to collisions and brute‑force attacks. It should never be used for production password storage.

<?php
// Registration
$username = $_POST['username'];
$password = $_POST['password'];
$hashed = md5($password); // insecure
// Store $hashed in the database

// Login
$input = $_POST['password'];
if (md5($input) === $stored_hash) {
    // authenticated (but insecure)
}
?>

2. Using password_hash (recommended)

PHP 5.5+ provides password_hash, which automatically selects a strong algorithm (default PASSWORD_BCRYPT), generates a random salt, and stores the salt together with the hash. Verification is performed with password_verify.

<?php
// Registration
$username = $_POST['username'];
$password = $_POST['password'];
$hash = password_hash($password, PASSWORD_DEFAULT); // bcrypt with random salt
// Store $hash in the database

// Login
$input = $_POST['password'];
$stored_hash = $row['password']; // fetched from DB
if (password_verify($input, $stored_hash)) {
    // login successful
} else {
    // invalid credentials
}
?>
password_hash

handles salting, algorithm upgrades, and provides resistance against modern attacks, making it the preferred method.

3. Using crypt with a manual salt

The low‑level crypt function can be used with a manually generated salt (e.g., via random_bytes or openssl_random_pseudo_bytes). The salt must include the algorithm identifier, such as $2y$10$ for bcrypt with a cost of 10.

<?php
// Registration
$username = $_POST['username'];
$password = $_POST['password'];
// Generate a 22‑character base64 salt
$salt = substr(str_replace('+', '.', base64_encode(random_bytes(16))), 0, 22);
$hash = crypt($password, '$2y$10$' . $salt); // bcrypt with manual salt
// Store $hash in the database

// Login
$input = $_POST['password'];
$stored_hash = $row['password']; // fetched from DB
if (crypt($input, $stored_hash) === $stored_hash) {
    // login successful
} else {
    // invalid credentials
}
?>

While crypt works, it requires careful construction of the salt and algorithm identifier. Using password_hash is simpler and less error‑prone.

Conclusion

For secure password storage in PHP, avoid md5 and raw crypt. Prefer password_hash (bcrypt) together with password_verify, which automatically manages salts and provides strong resistance to attacks.

MD5Backend Securitycryptpassword hashingpassword_hash
php Courses
Written by

php Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.