In PHP, crypt functions are often used for password hashing. It allows the security of hashing to be enhanced through salt value (Salt) to prevent security risks such as rainbow table attacks. However, many developers are accustomed to hard-code salt values when using crypt , which can lead to security risks. This article will discuss in detail how to avoid hard-coded salt values, thereby improving the security of password storage.
Hard-coded salt values refer to writing fixed salt strings directly into the code, such as:
$salt = '$6$rounds=5000$fixedsaltstring$';
$hash = crypt($password, $salt);
There are obvious risks in doing so:
Salt value reuse : All users' password hashs use the same salt, and the attacker can pre-calculate the attack by pre-calculating the attack.
Exposed salt value : If the source code is leaked and the attacker knows about the salt, the difficulty of hash cracking will be greatly reduced.
Difficult to scale : if you need to change the salt strategy, modifying the hard-coded part is extremely inflexible.
To avoid the above problems, it is recommended to dynamically generate unique and safe salts. Here are a few key points:
PHP's random_bytes() function can generate high-intensity random bytes, and salt can be generated by combining Base64 or similar encoding.
function generateSalt($length = 16) {
$bytes = random_bytes($length);
return substr(strtr(base64_encode($bytes), '+', '.'), 0, $length);
}
Different algorithms have different requirements for salt formats. Taking SHA-512 ( $6$ ) as an example, the format is:
$6$rounds=5000$saltstring$
Combined with dynamic salt:
$saltString = '$6$rounds=5000$' . generateSalt() . '$';
$hash = crypt($password, $saltString);
The hash returned by crypt contains salt information. When storing, you only need to store the complete hash without saving the salt separately.
When verifying, call crypt directly with input password and storage hash, and compare the results:
function verifyPassword($inputPassword, $storedHash) {
return crypt($inputPassword, $storedHash) === $storedHash;
}
<?php
// Generate dynamic salt
function generateSalt($length = 16) {
$bytes = random_bytes($length);
return substr(strtr(base64_encode($bytes), '+', '.'), 0, $length);
}
// Create a password hash
function createHash($password) {
$salt = '$6$rounds=5000$' . generateSalt() . '$';
return crypt($password, $salt);
}
// Verify password
function verifyPassword($inputPassword, $storedHash) {
return crypt($inputPassword, $storedHash) === $storedHash;
}
// Example usage
$password = 'mypassword123';
$hash = createHash($password);
echo "Hash value: $hash\n";
if (verifyPassword('mypassword123', $hash)) {
echo "Password verification succeeded!\n";
} else {
echo "Password verification failed!\n";
}
?>
Avoiding hard-coded salt values can significantly improve the security of password hashing. By using PHP's random number generation function, a unique salt value is created dynamically and a complete hash is stored in the database, which can effectively resist a variety of attack methods.