Using BCrypt is a common and best way to hash passwords, but a large number of developers still use old and weak algorithms, like MD5 and SHA1. Some developers do not even use hash salt. The new hashing API in PHP 5.5 aims to draw attention to BCrypt, making it easier to work with. In this article I will discuss the basics of using a new API for hashing in PHP.
The new password hashing API provides four simple functions:
- password_hash () - used to hash the password.
- password_verify () - used to check the password for compliance with the hash.
- password_needs_rehash () - used to verify the need to create a new hash.
- password_get_info () - returns the name of the hashing algorithm and various parameters used in hashing.
password_hash ()
Although the
crypt () function
is fairly safe, it is considered by many to be too complex. Some developers, in order not to mess with it, use weak salt and a weak algorithm to generate a hash, for example:
<?php $hash = md5($password . $salt);
But the
password_hash () function allows us to simplify our life and secure our code. When you need to get a password hash, just feed it to this function, and it will return a hash that can be stored in the database.
<?php $hash = password_hash($passwod, PASSWORD_DEFAULT);
That's all! The first parameter is the password string that needs to be hashed, and the second parameter specifies the algorithm that should be used to generate the hash.
The default algorithm is currently BCrypt, but a stronger algorithm may be installed by default sometime in the future, and perhaps it will generate larger strings. If you use
PASSWORD_DEFAULT in your projects, be sure to store the hash in a column larger than 60 characters. Setting the column size to 255 can be a good choice. You can also use
PASSWORD_BCRYPT as the second parameter. In this case, the result will always be 60 characters.
')
The main thing here is that you do not need to worry about the value of salt and the cost of calculating the hash. The new API will do this for you. And salt is part of the hash, so you don’t have to store it separately. If you want to use your own salt (or calculation cost), you can do this by passing the third argument of the function:
<?php $options = [ 'salt' => custom_function_for_salt(),
Thus, you will always keep up with current security measures. If PHP later decides to use a more powerful hashing algorithm, your code can use it without modification.
password_verify ()
Now that you have seen how to generate hashes with the new API, let's see how to verify the password. We simply take the hash from the database, and the password entered by the user and transfer them to this function.
password_verify () returns
true if the hash matches the specified password.
<?php if (password_verify($password, $hash)) {
Salt is part of the hash and that is why we do not have to bother with it separately.
password_needs_rehash ()
What if you need to change the salt or the cost of the calculation for saved passwords? For example, you decide to increase the security and increase the cost of the calculation or change the salt. Or PHP has changed the default hashing algorithm. In these cases, you would like to change existing password hashes. The
password_needs_rehash () function checks whether the password hash uses a specific algorithm, salt, and computation cost.
<?php if (password_needs_rehash($hash, PASSWORD_DEFAULT, ['cost' => 12])) {
Keep in mind that you need to do this when a user logs into the site, as this is the only time you have access to his unencrypted password.
password_get_info ()
The
password_get_info () function takes a hash and returns an associative array of three elements:
- algo - a constant that identifies a specific algorithm
- algoName - the name of the algorithm used
- options - various options used when generating the hash
Conclusion
The new password hashing API is definitely more convenient than messing around with
crypt () . If your site is currently running PHP 5.5, then I strongly recommend using the new hashing API. Those who use PHP 5.3.7 (or a newer version) can use a library called
password_compat which emulates this API and automatically disables itself when using PHP version 5.5+.
Original.