When using PHP's crypt() function for password hashing, the security of salt directly affects the security of password storage. The function of salt value is to prevent the same password from generating the same hash value, thereby effectively resisting rainbow table attacks. Therefore, it is very important to generate a safe and reliable salt value.
The salt value is a random string that is appended to the password and then hashed. A good salt value requires the following characteristics:
Unique and random: Each password corresponds to a unique salt value.
Long enough: avoid the salt value being easily guessed.
Suitable for hashing algorithms: Different algorithms have requirements for the length and format of salt value.
crypt() supports multiple encryption algorithms, and different algorithms have different requirements for salt value formats. Common algorithms and salt value formats are as follows:
DES : The salt value is 2 characters in length.
MD5 : Start with $1$ , with a maximum of 8 characters in salt value, such as $1$abcdefgh$ .
Blowfish : Start with $2a$ or $2y$ , followed by a two-digit cost factor and a salt value of 22 characters, such as $2y$10$abcdefghijklmnopqrstuv .
SHA-256 : Start with $5$ , followed by salt value, up to 16 characters long.
SHA-512 : Start with $6$ , followed by salt value, up to 16 characters long.
Blowfish ( $2y$ ) or SHA-512 ( $6$ ) algorithms are recommended because they are safer and support longer salt values.
The key to generating salt values is to use safe random number generation functions and comply with the salt value format requirements of the corresponding algorithm.
Sample code:
<?php
function generateSalt($algo = 'bcrypt') {
switch ($algo) {
case 'bcrypt':
// Blowfish need 22 indivual Base64 character,The cost is 10
$cost = 10;
// Using random bytes,转换成可用的character集
$randomBytes = random_bytes(16);
$base64String = substr(strtr(base64_encode($randomBytes), '+', '.'), 0, 22);
return sprintf('$2y$%02d$%s', $cost, $base64String);
case 'sha512':
// SHA-512 Maximum allowable16character盐
$randomBytes = random_bytes(12);
return '$6$' . substr(strtr(base64_encode($randomBytes), '+', '.'), 0, 16);
default:
throw new Exception("Unsupported algorithm");
}
}
// Example of usage
$password = 'user_password';
$salt = generateSalt('bcrypt');
$hash = crypt($password, $salt);
echo "Salt value:$salt\n";
echo "Hash value:$hash\n";
?>
In the above code:
random_bytes() is used to generate safe random bytes.
base64_encode() is encoded and replaced with + to meet the salt value format requirements.
Blowfish uses cost factor 10, which is both safe and reasonable in performance.
The generated salt value is strictly in the format required by crypt() .
PHP 7.2 and above strongly recommend using the built-in password_hash() function, which automatically handles salt value generation and algorithm selection, simplified and safer:
<?php
$password = 'user_password';
$hash = password_hash($password, PASSWORD_BCRYPT);
echo $hash;
?>
If you have to use crypt() manually, be sure to ensure that the salt value is safe and random and the format is correct, otherwise it will easily lead to hash weakening.