In PHP, password_hash() and password_verify() are functions used for password encryption and verification. When used together, they significantly enhance the security of password storage, helping prevent leaks and brute-force attacks. However, many developers are still unsure about the encryption algorithms they use and how they are related. This article will explore their encryption algorithms and the relationship between the two.
The password_hash() function, introduced in PHP 5.5 and later, is used to convert a user’s plaintext password into an encrypted hash. It uses modern hashing algorithms (such as bcrypt) and automatically generates a “salt.” A salt is random data added to ensure that the same plaintext password will produce a different hash each time it’s encrypted.
By default, password_hash() uses the bcrypt algorithm. The generated hash already contains the salt, so there’s no need to store it separately. bcrypt also has an adaptive feature: by increasing the cost factor, developers can raise the computational complexity, making brute-force attacks much harder.
Example code:
<span><span><span class="hljs-variable">$password</span></span><span> = </span><span><span class="hljs-string">'my_secure_password'</span></span><span>;
</span><span><span class="hljs-variable">$hashedPassword</span></span><span> = </span><span><span class="hljs-title function_ invoke__">password_hash</span></span><span>(</span><span><span class="hljs-variable">$password</span></span><span>, PASSWORD_BCRYPT);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$hashedPassword</span></span><span>;
</span></span>
The password_verify() function verifies whether a given password matches the stored hash. Its purpose is to compare a user’s input during login against the encrypted password stored in the database. password_verify() automatically extracts the salt from the stored hash, applies the same algorithm to the input password, and compares the results.
It’s important to note that password_verify() determines which algorithm to use based on the stored hash. Developers don’t need to manually provide the salt or algorithm—it automatically handles the verification process using the information embedded in the hash.
Example code:
<span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">password_verify</span></span><span>(</span><span><span class="hljs-variable">$userInputPassword</span></span><span>, </span><span><span class="hljs-variable">$storedHash</span></span><span>)) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Password is correct!"</span></span><span>;
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Invalid password!"</span></span><span>;
}
</span></span>
The close relationship between password_hash() and password_verify() lies in the fact that they rely on the same encryption algorithm for processing and verification. Specifically:
Password Encryption: password_hash() transforms plaintext passwords into hashes using the specified algorithm (by default, bcrypt). The resulting hash includes the salt and other algorithm parameters (such as the cost factor).
Password Verification: password_verify() reads the algorithm and salt information from the hash, applies the same algorithm (such as bcrypt) to the user’s input, and compares the results against the stored hash.
Therefore, password_verify() must use the exact same algorithm and parameters as password_hash(). If the hash was generated using bcrypt, password_verify() will automatically use bcrypt for verification as well.
Although password_hash() defaults to bcrypt, it also supports other algorithms. Since PHP 7.2, it has included support for argon2i and argon2id, which are even stronger. argon2 is a modern hashing algorithm that provides better resistance to GPU-powered brute-force attacks compared to bcrypt.
Example code using argon2i:
<span><span><span class="hljs-variable">$hashedPassword</span></span><span> = </span><span><span class="hljs-title function_ invoke__">password_hash</span></span><span>(</span><span><span class="hljs-variable">$password</span></span><span>, PASSWORD_ARGON2I);
</span></span>
If a password is hashed using the argon2 algorithm, password_verify() will automatically recognize it and perform verification with the corresponding algorithm.
password_hash() and password_verify() are two crucial functions in PHP for password encryption and verification. Their encryption algorithms are closely connected: password_hash() generates the hash, and password_verify() validates passwords against that hash. They are typically used together to ensure secure password storage. While bcrypt is the default algorithm, PHP also supports stronger options such as argon2, which developers can choose depending on their security requirements.
By understanding the relationship between the algorithms used by password_hash() and password_verify(), developers can design safer password storage and verification mechanisms, thereby strengthening application security.