Функция password_hash
На самом деле функция md5
и соление
пароля с ее помощью считается устаревшим.
Мы изучали ее, чтобы вы поняли дальнейший
материал, а также потому, что вы можете столкнуться
с этим, работая с чужими проектами.
Существует более совершенный способ получить
соленый пароль. Для этого используется функция
password_hash
. Первым параметром она
принимает строку, а вторым - алгоритм шифрования
(о нем позднее), и возвращает хеш этой строки
вместе с солью.
Попробуйте несколько раз запустите этот код:
<?php
echo password_hash('12345', PASSWORD_DEFAULT);
?>
Вы каждый раз будете получать разный результат и в этом результате первая часть строки будет являться солью, а вторая часть - соленым паролем.
Пусть у нас есть хеш, полученный из функции
password_hash
и какой-то пароль. Чтобы
проверить, это хеш этого пароля или нет,
следует использовать функцию password_verify
- первым параметром она принимает пароль,
а вторым - хеш, и возвращает true
или false
.
Давайте посмотрим на примере:
<?php
$password = '12345'; // пароль
$hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // хеш
if (password_verify($password, $hash)) {
// хеш от этого пароля
} else {
// хеш не от этого пароля
}
?>
Что это дает нам на практике: мы можем не создавать в базе данных отдельное поле для хранения соли, не заморачиваться с генерированием этой соли - PHP все сделает за нас!
То есть получится, что в базе данных в поле
password
мы будем хранить соленый
пароль вместе с его солью. При этом хешированный
пароль будет иметь большую длину. Поэтому
в базе данных нам нужно исправить размер
поля с паролем и установить ее в 60
символов.
Теперь давайте поправим код регистрации. Вот то, что есть сейчас:
<?php
function generateSalt()
{
$salt = '';
$saltLength = 8; // длина соли
for($i = 0; $i < $saltLength; $i++) {
$salt .= chr(mt_rand(33, 126)); // символ из ASCII-table
}
return $salt;
}
$salt = generateSalt(); // соль
$password = md5($salt . $_POST['password']); // преобразуем пароль в соленый хеш
?>
С помощью password_hash
мы сократим это до:
<?php
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
?>
Аналогичным образом подправится код авторизации:
<?php
$login = $_POST['login'];
$query = "SELECT * FROM users WHERE login='$login'"; // получаем юзера по логину
$res = mysqli_query($link, $query);
$user = mysqli_fetch_assoc($res);
if (!empty($user)) {
$hash = $user['password']; // соленый пароль из БД
// Проверяем соответствие хеша из базы введенному паролю
if (password_verify($_POST['password'], $hash)) {
// все ок, авторизуем...
} else {
// пароль не подошел, выведем сообщение
}
} else {
// пользователя с таким логином нет, выведем сообщение
}
?>
Переделайте вашу авторизацию и регистрацию на новые изученные функции.