Password_hash Function
In fact, the md5 function and salting
passwords with it is considered outdated.
We studied it so that you understand the further
material, and also because you might encounter
it when working with others' projects.
There is a more advanced way to get
a salted password. For this, the function
password_hash is used. Its first parameter is
the string, and the second is the encryption algorithm
(more on that later), and it returns the hash of this string
along with the salt.
Try running this code several times:
<?php
echo password_hash('12345', PASSWORD_DEFAULT);
?>
You will get a different result each time, and in this result, the first part of the string will be the salt, and the second part - the salted password.
Let's say we have a hash obtained from the function
password_hash and some password. To
check if this is the hash of that password or not,
you should use the function password_verify
- its first parameter is the password,
and the second is the hash, and it returns true
or false.
Let's look at an example:
<?php
$password = '12345'; // password
$hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // hash
if (password_verify($password, $hash)) {
// hash is from this password
} else {
// hash is not from this password
}
?>
What does this give us in practice: we don't have to create a separate field in the database for storing the salt, not bother with generating this salt - PHP will do everything for us!
So it turns out that in the database, in the field
password we will store the salted
password along with its salt. At the same time, the hashed
password will have a greater length. Therefore,
in the database, we need to correct the size
of the password field and set it to 60
characters.
Now let's fix the registration code. Here is what we have now:
<?php
function generateSalt()
{
$salt = '';
$saltLength = 8; // salt length
for($i = 0; $i < $saltLength; $i++) {
$salt .= chr(mt_rand(33, 126)); // symbol from ASCII-table
}
return $salt;
}
$salt = generateSalt(); // salt
$password = md5($salt . $_POST['password']); // convert password to salted hash
?>
Using password_hash we can reduce this to:
<?php
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
?>
The authorization code will be adjusted similarly:
<?php
$login = $_POST['login'];
$query = "SELECT * FROM users WHERE login='$login'"; // get user by login
$res = mysqli_query($link, $query);
$user = mysqli_fetch_assoc($res);
if (!empty($user)) {
$hash = $user['password']; // salted password from DB
// Check if the hash from the database matches the entered password
if (password_verify($_POST['password'], $hash)) {
// all ok, authorize...
} else {
// password didn't match, show message
}
} else {
// user with this login doesn't exist, show message
}
?>
Redo your authorization and registration using the newly learned functions.