Языки программирования

Безопасное хеширование паролей в PHP

Такие хеширующие алгоритмы как MD5, SHA1 и SHA256 были спроектированы очень быстрыми и эффективными. При наличии современных технологий и оборудования, стало довольно просто выяснить результат этих алгоритмов методом «грубой силы» для определения оригинальных вводимых данных.
Из-за той скорости, с которой современные компьютеры могут «обратить» эти хеширующие алгоритмы, многие профессионалы компьютерной безопасности строго не рекомендуют использовать их для хеширования паролей.
С PHP 5.5 появилось API хеширования паролей, которое безопасно работает и с хешированием и с проверкой паролей.
API хеширования паролей предоставляет простую в использовании обертку функции crypt() и некоторых других алгоритмов хеширования пароля для легкого создания и управления паролями.
Для сборки этого расширения не требуются внешние библиотеки. Для хеширования паролей через Argon2 требуется «libargon2«. Начиная с PHP 7.3.0, требуется libargon2 версии 20161029 или выше.
Хэш API состоит из следующих функций:
  1. password_get_info — Возвращает информацию о заданном хеше.
  2. password_hash — Создает хеш пароля.
  3. password_needs_rehash — Проверяет, что указанный хеш соответствует заданным опциям.
  4. password_verify — Проверяет, соответствует ли пароль хешу.

password_hash()

Функция password_hash() упрощает процесс настолько, насколько это возможно. Если вам нужно создать хэш пароля, вызовите эту функцию и запишите значение в базу данных. Пример:
$hash = password_hash($passwod, PASSWORD_DEFAULT);
Первый параметр — это строка представляющая собой пароль; второй — алгоритм, который будет применён.
В данный момент поддерживаются следующие алгоритмы:
PASSWORD_DEFAULT — используется алгоритм bcrypt (по умолчанию с PHP 5.5.0).
PASSWORD_BCRYPT — использует алгоритм CRYPT_BLOWFISH. Генерирует стандартный хеш, совместимый с генерированным функцией crypt() с использованием идентификатора «$2y$». В результате будет сгенерирована строка длиной 60 символов, или FALSE в случае возникновения ошибки.
PASSWORD_ARGON2I — Использовать алгоритм хеширования Argon2i. Этот алгоритм доступен только если PHP собран с поддержкой Argon2.
PASSWORD_ARGON2ID — Использовать алгоритм хеширования Argon2id. Этот алгоритм доступен только если PHP собран с поддержкой Argon2.
Если вы используете PASSWORD_DEFAULT, то знайте, что на выходе получите строку из более 60 символов. Она может быть и больше, особенно, при использовании других алгоритмов, так что в таблице размер поля можете выставить 255.
Важно понять, что вам самим не нужно передавать соль или параметр cost (стоимость — количество раундов подготовки ключей). Новый API сделает это за вас.

password_verify()

Функция password_verify() принимает пароль в обычном виде и его хэш. В зависимости от результатов проверки, возвращает true или false. Пример:
if (password_verify($password, $hash)) {
    // Успех!
}
else {
    // Провал
}
// password - полученный пароль от пользователя
// hash - хеш хранящийся в базе данных

password_needs_rehash()

Если необходимо обновить параметры соли или стоимости, то в этом случае, можно воспользоваться функцией password_needs_rehash() для проверки данного факта:
if (password_needs_rehash($hash, PASSWORD_DEFAULT, ['cost' => 12])) {
// необходимо создать хэш пароля ещё раз
$hash = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]);
}
Данную операцию можно делать при входе пользователя в систему, ведь только тогда у нас есть доступ к паролю в явном виде.

password_get_info()

password_get_info() возвращает параметры хеширования:
  1. algo – константа с названием алгоритма
  2. algoName – название алгоритма
  3. options – различные настройки
Самоучитель по PHP