In modern web application development, the secure storage of user passwords is crucial. PHP provides a variety of password encryption methods, among which the crypt() function is a flexible and powerful encryption tool. This article will introduce how to securely encrypt and verify user passwords using PHP's crypt() function, and explain how to avoid common security traps.
crypt() is a password hash function that supports multiple encryption algorithms. The specific algorithm depends on the "salt" you pass in. Different algorithms have different salt formats, such as SHA-256 , SHA-512 , etc. Reasonable use of crypt() can generate strong password hashes and increase the difficulty of cracking.
string crypt(string $password, string $salt);
$password is the plaintext password entered by the user.
$salt is used to specify the encryption algorithm and random salt value to ensure that the results of each encryption are different.
The function of salt is to prevent rainbow table attacks, and each password should have a unique salt value. For modern algorithms, salt should contain algorithm identification, number of iterations, and random characters.
The following example generates a salt based on the SHA-512 algorithm:
function generateSalt($length = 16) {
$randomBytes = random_bytes($length);
return '$6$rounds=5000$' . substr(strtr(base64_encode($randomBytes), '+', '.'), 0, 16) . '$';
}
$6$ means using SHA-512.
rounds=5000 controls the number of hash iterations, the larger the safer it is but time-consuming.
Random strings ensure uniqueness of salt.
Combining the salt generated above, you can encrypt the password like this:
$password = 'user_password_here';
$salt = generateSalt();
$hash = crypt($password, $salt);
$hash is the password hash string stored in the database.
During verification, you cannot directly compare the password and hash, but call crypt() with the user input password, and pass the stored hash as the salt. The function will automatically extract the salt and encrypt the password:
function verifyPassword($inputPassword, $storedHash) {
$hash = crypt($inputPassword, $storedHash);
return hash_equals($hash, $storedHash);
}
Use hash_equals() to prevent timing attacks and ensure relatively safe.
<?php
// Generate a salt function
function generateSalt($length = 16) {
$randomBytes = random_bytes($length);
return '$6$rounds=5000$' . substr(strtr(base64_encode($randomBytes), '+', '.'), 0, 16) . '$';
}
// Encrypted password when registering
function encryptPassword($password) {
$salt = generateSalt();
return crypt($password, $salt);
}
// Verify password when logging in
function verifyPassword($inputPassword, $storedHash) {
$hash = crypt($inputPassword, $storedHash);
return hash_equals($hash, $storedHash);
}
// Example
$userPassword = 'MySecurePass123';
$storedHash = encryptPassword($userPassword);
echo "Encrypted hash: " . $storedHash . "\n";
$inputPassword = 'MySecurePass123';
if (verifyPassword($inputPassword, $storedHash)) {
echo "Password verification succeeded!";
} else {
echo "Error password!";
}
?>
Try to use password_hash() and password_verify() of PHP 7.2+ , which encapsulate more modern and secure algorithms, but if you have to use crypt() for special reasons, please refer to the above method.
Regularly update the password hashing strategy to increase the number of iterations.
The hash string stored in the database contains salt and algorithm information, and there is no need to store salt separately.