PHP security: where and how to store passwords. Part 2

Hello! Last week, we published the first part of this article, which caused a serious holivar.

One of the main complaints was the lack of mention in the article. password_hash, as we promised, we’ll start the second part of this material with password hashing using password_hash. We also remind you that the writing of this article was inspired by the launch of a new group on the course "Backend PHP Developer", but this material has no relation to the training program.

You can learn more about the training program at the open house day, and using the example of a free webinar on the topic “ServerLess PHP”, you can evaluate the format of the lectures.

Perhaps this is where we conclude the already protracted preface and go directly to the article.

Password hash with password_hash

This function creates a password hash in accordance with the parameters that we set for it. It uses a one-way algorithm.

We can choose which type of algorithm to use by setting one of the constants of our choice:

  • PASSWORD_DEFAULT from PHP 5.5 uses Bcrypt as the default algorithm. However, over time, this changes as new, more secure algorithms or other factors are discovered.
  • PASSWORD_BCRYPT creates a hash crypt (). Usually it contains 60 characters, it can be identified by its identifier in the format "$ 2y $".
  • PASSWORD-ARGON2I Argon2 is currently one of the most secure hashing algorithms. It is only available if PHP was compiled with Argon2.
  • PASSWORD_ARGON2ID This hash algorithm also belongs to the Argon2 family and uses the version of Argon2ID, not I. For it to work, it is also necessary that PHP be compiled using Argon2.

This function also has an optional parameter, which consists of an associative array that accepts several keys in accordance with the selected algorithm.
If you prefer to use Bcrypt, the key of this sequence will be the value of cost.

If you select an algorithm that uses Argon2, the keys for the associative array are: memory_cost (an integer indicating the maximum amount of memory needed to calculate the hash), time_cost (an integer indicating the maximum time required to calculate the hash) and thread (another integer indicating the number of threads used to calculate the hash).

Do not specify a parameter salt in PHP 7.0, otherwise get a warning about the deprecated approach.

Now we know what elements are needed to use the function. password_hash (). Let's see how to prescribe it.

echo password_hash ("MySuperPass", PASSWORD_DEFAULT);
$ 2y $ 10 $ TLayAY8ZaAZ9FE50EylGYO9oEgrb7gsw1yzJemHdBu1gOQfyWrEUm
$ options = ['cost' => 12,];

echo password_hash ("MySuperPass", PASSWORD_BCRYPT, $ options);
$ 2y $ 12 $ jhmTbxAuZXVtX2y.Jc8iy.dW / NENqVCeq2vuoFI9 / oa4. / YlzhpYO

echo password_hash ('rasmuslerdorf', PASSWORD_ARGON2I);
$ argon2i $ v = 19 $ m = 1024, t = 2, p = 2 $ YzJBSzV4TUhkMzc3d3laeg $ zqU / 1IN0 / AogfP4cmSJI1vc8lpXRW9 / S0sYY2i2jHT0

At first, it is recommended to test this function on your servers and configure the cost parameter so that the execution of the function takes less than 100 milliseconds on interactive systems.

The script in the above example will help you set the optimal cost value for your hardware.

User Password Verification

You gave users the opportunity to register in your new application, they can enter their password there, and you know very well how to handle this password.

By hashing data in accordance with the latest security trends, you do not store anything in encrypted form, and your server is hidden in a basement of 10 meters depth.

Now what?

Now you must allow users to log in to the application. To do this, PHP has a built-in function that checks the password matching the hashed sequence. This function is called password_verify (). It works like this:

$ hash = '$ 2y $ 07 $ BCryptRequires22Chrcte / VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';
if (password_verify ('rasmuslerdorf', $ hash)) {
    echo 'Password is correct!';
} else {
    echo 'Password is not correct!';

It has two parameters, and both must have a sequence format. The first parameter is the password that the user entered into the account login form. The second parameter is the directly hashed data with which we will consult.

As a result, we get a logical value, ready for use in conditional operations. Thus, we can either let the user into the application or inform him that something went wrong.

This function works due to the fact that in the previous step (when we had the password hashed), the value returned from password_hash, included the algorithm used by us, cost and salt.

Thus, we have access to all the information necessary for password_verify ().

The algorithm of the user registration system on PHP
I hope you now understand what security measures PHP developers take when handling passwords.

First you need to check for a post-request, and then select and calculate the number of users whose data matches the entered.

If everything went well, we verify the password and send the user to the start page. Otherwise, for example, in Javascript we display a warning window with an error notification.


Now you know how to ensure the security of your application and how to handle passwords correctly. Following useful recommendations is not just a standard that you must adhere to, but a development path that should be pleasant to follow.
Learn new techniques similar to how you just learned. Add additional functionality and experiment with the code until you get excellent web development skills – whether it is PHP or any other language that opens up no less opportunities!

Read the first part

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *