In PHP, crypt() is a hash encryption function widely used in password handling and data encryption scenarios. However, many developers are surprised to find that when using crypt() to encrypt the same content, the result is always the same:
This article will take you through the reasons behind this phenomenon and teach you how to correctly and securely use crypt().
crypt() is essentially a hash function designed not to encrypt data but to generate irreversible hash values, commonly used for password verification.
The function prototype is as follows:
string crypt(string $string, string $salt)
It takes two parameters:
$string: The string to be encrypted.
$salt: The "salt" used during encryption, which affects the hash result.
If you pass the same $salt, encrypting the same $string will naturally result in the same output. This is why you always see the same "encryption result".
This happens because when you call crypt(), you may have used a fixed salt or not passed the second parameter $salt at all.
When crypt() in PHP is not provided with a $salt, it tries to use some system default mechanisms. However, this mechanism might result in “using the same salt by default” on some systems, leading to "the same input always producing the same output".
Take a look at the example below:
echo crypt("mypassword", "m6"); // Using a fixed salt
Each time you run this code, no matter how many times, the output will always be the same. This means that if an attacker knows you are using a fixed salt, they can pre-compute a hash table and attack your system.
**The correct approach is to use a random salt value.** Each time you generate a password hash for a user, create a unique salt and store it in the database. This way, even if two users have the same password, their hash values will be different.
PHP recommends using a method with an automatically generated salt, such as using the password_hash() function, which was introduced in PHP 5.5+ and provides a more secure method:
$password = 'mypassword';
$hash = password_hash($password, PASSWORD_BCRYPT);
This function automatically generates a unique salt for you and appends it to the result. Each time you run it, you'll get a different result:
// Every output is different
$hash1 = password_hash('mypassword', PASSWORD_BCRYPT);
$hash2 = password_hash('mypassword', PASSWORD_BCRYPT);
But they can still be verified against the original password using password_verify().
If you must use crypt(), you should manually generate a random salt. Here's an example:
function generate_salt($length = 22) {
return substr(strtr(base64_encode(random_bytes($length)), '+', '.'), 0, $length);
}
<p>$password = 'mypassword';<br>
$salt = '$2y$10$' . generate_salt(); // Using Blowfish algorithm<br>
$hash = crypt($password, $salt);<br>
Each time you call this function, a different salt will be generated, which naturally results in a different encrypted outcome.
The encrypted result should be stored in the database for subsequent verification. Example code is as follows:
// Storing
$hash = crypt($password, $salt);
// Save to the database
<p>// Verifying<br>
if (hash_equals($hash, crypt($inputPassword, $hash))) {<br>
echo "Password correct";<br>
} else {<br data-is-only-node="">
echo "Password incorrect";<br>
}<br>
Note that the second parameter of crypt() can directly take the already encrypted hash value, and PHP will automatically extract the salt from it.
crypt() returns the same result because you used the same salt.
To ensure security, use a random salt or directly use password_hash().
It is not recommended to continue using crypt() in new projects unless there is a specific requirement.
Always avoid hardcoding salt to prevent rainbow table attacks.
When developing systems that handle user passwords, always prioritize security. A proper understanding of how crypt() works will help you build a more robust and reliable application system.