Когда то для хеширования пароля достаточно было функции "md5", но сегодня этого мало: https://secure.php.n ... swords.fasthash:
Почему популярные хеширующие функции, такие как md5() и sha1() не подходят для паролей?
Такие хеширующие алгоритмы как MD5, SHA1 и SHA256 были спроектированы очень быстрыми и эффективными. При наличии современных технологий и оборудования, стало довольно просто выяснить результат этих алгоритмов методом "грубой силы" для определения оригинальных вводимых данных.
Из-за той скорости, с которой современные компьютеры могут "обратить" эти хеширующие алгоритмы, многие профессионалы компьютерной безопасности строго не рекомендуют использовать их для хеширования паролей.
Такие хеширующие алгоритмы как MD5, SHA1 и SHA256 были спроектированы очень быстрыми и эффективными. При наличии современных технологий и оборудования, стало довольно просто выяснить результат этих алгоритмов методом "грубой силы" для определения оригинальных вводимых данных.
Из-за той скорости, с которой современные компьютеры могут "обратить" эти хеширующие алгоритмы, многие профессионалы компьютерной безопасности строго не рекомендуют использовать их для хеширования паролей.
PHP.NET рекомендует для хеширования пароля использовать функцию password_hash, а для проверки пароля функцию password_verify. Беда в том, что не все понимают, как пользоваться этими функциями. Сейчас, я попробую объяснить.
Описания функций можно прочитать на официальном сайте PHP:
password_hash: http://php.net/manua ... ssword-hash.php.
password_verify: http://php.net/manua ... word-verify.php.
И так, при регистрации или смене пароля, сценарий с формы принимает пароль в таком виде, как его ввел пользователь, этот пароль обрабатываем функцией password_hash:
$hash = password_hash($password, PASSWORD_DEFAULT);
Теперь переменная
$hash
- это захешированный пароль, его та и сохраняем в БД, как пароль пользователя. Дальше, при авторизации пользователя, необходимо проверить пароль, то есть сравнить его с тем, что сохранен в БД, если пароли совпадаю, то пользователь авторизуется, если нет, то, конечно, выдаем ошибку. Тут обычное сравнение строк, типа:
$hash = password_hash($password, PASSWORD_DEFAULT);
if ($hash == $user['password'])
{
// Пароли совпадают
}
Не подойдет, так как функция password_hash каждый раз возвращает разную строку (хэш) обрабатывая один и тот же пароль:
$hash = password_hash('строка', PASSWORD_DEFAULT);
echo $hash;
1 обработка: $2y$10$KibpNRHBjIfipumOXvctdeNSjelvLzWrtbZ6Wn1aHoXQxp58UW2QS
2 обработка: $2y$10$SG6hMn4sFEP1c9nDvkkz2OtCR3Eu7PaMCc9fcGsFS8l1FjixniWIC
3 обработка: $2y$10$wi.Yv/3u0w31ks42EXEOIOcBiLVUT6MticfpjzEJdPQtKly52TDvm
И так далее...
2 обработка: $2y$10$SG6hMn4sFEP1c9nDvkkz2OtCR3Eu7PaMCc9fcGsFS8l1FjixniWIC
3 обработка: $2y$10$wi.Yv/3u0w31ks42EXEOIOcBiLVUT6MticfpjzEJdPQtKly52TDvm
И так далее...
В общем при простом сравнении строк, пароль всегда будет неправильным.
Проверять хэш пароля, что был создан функцией password_hash, следует функцией password_verify. Так же сценарий при авторизации пользователя принимает пароль в том виде, что вводил пользователь и в таком же виде вставляем его в функцию password_verify первым параметром. Второй параметр должен быть хешированный пароль, что сохранен в БД:
if (password_verify($password, $user['password']))
{
// Пароли совпадают
}
Вот, собственно, и все.
В PHP 7.2 появился новый тип хеширования: "argon2". Чтобы хэшировать пароль этим типом, указывайте вторым параметром в функции password_hash константу PASSWORD_ARGON2I:
$hash = password_hash('строка', PASSWORD_ARGON2I);