password_hash

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

password_hashСоздаёт хеш пароля

Описание

password_hash(#[\SensitiveParameter] string $password, string|int|null $algo, array $options = []): string

Функция password_hash() создаёт хеш пароля через сильный необратимый алгоритм хеширования.

Поддерживаются следующие алгоритмы:

  • PASSWORD_DEFAULT — функция выберет алгоритм bcrypt (по умолчанию с PHP 5.5.0). Обратите внимание, алгоритм может измениться на более сильный, когда такой добавится в PHP. При изменении алгоритма и длина результата также может измениться. Поэтому длину поля для хранения в базе данных лучше устанавливать более 60 символов (255 символов будет хорошим значением).
  • PASSWORD_BCRYPT — функция выберет алгоритм CRYPT_BLOWFISH. Генерирует стандартный хеш с идентификатором "$2y$", совместимый с тем, который генерирует функция crypt(). В результате будет сгенерирована строка длиной 60 символов или false, если возникла ошибка.
  • PASSWORD_ARGON2I — функция выберет алгоритм хеширования Argon2i. Этот алгоритм будет доступен, только если PHP собран с поддержкой Argon2.
  • PASSWORD_ARGON2ID — функция выберет алгоритм хеширования Argon2id. Этот алгоритм будет доступен, только если PHP собран с поддержкой Argon2.

Поддерживаемые опции для PASSWORD_BCRYPT:

  • salt (string) — для самостоятельного задания соли для хеширования. Обратите внимание, что это приведёт к переопределению и предотвратит автоматическое создание соли.

    Если не задали, то функция password_hash() будет генерировать случайную соль для каждого хешируемого пароля. Это предпочтительный режим работы.

    Внимание

    Эту опцию объявили устаревшей. Рекомендуется использовать автоматически генерируемую соль. Начиная с PHP 8.0.0 соль, которую задали явно, игнорируется.

  • cost (int) — задаёт алгоритмическую сложность. Пример с этой опцией можно посмотреть на странице, посвящённой функции crypt().

    Если не задано, то будет выбрано значение по умолчанию: 10. Это хорошая базовая стоимость, но можно увеличить её, если позволяет производительность оборудования.

Поддерживаемые опции для PASSWORD_ARGON2I и PASSWORD_ARGON2ID:

  • memory_cost (int) — максимальный размер памяти (в килобайтах), которая будет использована для вычисления хеша Argon2. По умолчанию будет выбрано значение константы PASSWORD_ARGON2_DEFAULT_MEMORY_COST.

  • time_cost (int) — максимально возможное время, которое можно потратить на вычисление хеша Argon2. По умолчанию будет выбрано значение константы PASSWORD_ARGON2_DEFAULT_TIME_COST.

  • threads (int) — количество потоков, которые можно задействовать для вычисления хеша Argon2. По умолчанию будет выбрано значение константы PASSWORD_ARGON2_DEFAULT_THREADS.

    Внимание

    Доступно только тогда, когда в PHP доступен модуль libargon2, но не при реализации libsodium.

Список параметров

password

Пользовательский пароль.

Предостережение

Использование алгоритма PASSWORD_BCRYPT приведёт к обрезанию поля password до максимальной длины — 72 байта.

algo

Константа алгоритма хеширования пароля, который будет использовать функция.

options

Ассоциативный массив с опциями. За документацией по поддерживаемым опциям для каждого алгоритма обратитесь к разделу Константы алгоритмов хеширования паролей.

Если не задали, функция использует стандартная стоимость, и сгенерирует соль автоматически.

Возвращаемые значения

Функция возвращает хешированный пароль.

Алгоритм, который выбрала функция, стоимость и соль возвращаются как часть хеша. Поэтому информацию, которая требуется для проверки хеша, функция включит в хеш. Это позволит функции password_verify() проверять хеш без отдельного хранения информации о соли и алгоритме.

Список изменений

Версия Описание
8.3.0 Функция password_hash() теперь устанавливает базовое исключение Random\RandomException в качестве Exception::$previous, если выбрасывается ошибка ValueError из-за сбоя во время генерации соли.
8.0.0 Функция password_hash() больше не возвращает значение false, если возникла ошибка. Вместо этого функция выбросит исключение ValueError, если алгоритм хеширования пароля недействителен, или Error, если хеширование пароля не удалось из-за неизвестной ошибки.
8.0.0 Параметр algo теперь принимает значение null.
7.4.0 Параметр algo теперь ожидает строку (string), но всё ещё принимает целое число (int) для обратной совместимости.
7.4.0 Модуль sodium обеспечивает альтернативную реализацию паролей Argon2.
7.3.0 Добавили поддержку алгоритма хеширования паролей Argon2id через алгоритм PASSWORD_ARGON2ID.
7.2.0 Добавили поддержку хеширующего алгоритма Argon2i через алгоритм PASSWORD_ARGON2I.

Примеры

Пример #1 Пример использования функции password_hash()

<?php

/**
* Просто хотим захешировать пароль с настройками по умолчанию.
* Значит, будет выбран алгоритм BCRYPT и результат будет длиной 60 символов.
*
* Помните, что алгоритм по умолчанию может измениться в будущем, так что
* имеет смысл заранее позаботиться о том, чтобы система хранения хешей
* смогла хранить более 60 символов (а лучше 255)
*/
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);

?>

Вывод приведённого примера будет похож на:

$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

Пример #2 Пример использования функции password_hash() с ручным указанием стоимости

<?php

/**
* Тут увеличиваем алгоритмическую стоимость BCRYPT до 12.
* Но это никак не скажется на длине полученного результата, она останется 60 символов
*/
$options = [
'cost' => 12,
];

echo
password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options);

?>

Вывод приведённого примера будет похож на:

$2y$12$QjSH496pcT5CEbzjD/vtVeH03tfHKFy36d4J0Ltp3lRtee9HDxY3K

Пример #3 Пример поиска хорошего значения стоимости для функции password_hash()

<?php

/**
* Этот код замерит скорость выполнения операции с разными значениями алгоритмической сложности хеширования
* на вашем сервере и определит
* его максимальное значение, не приводящее к деградации производительности. Хорошее базовое
* значение — 10, но если ваш сервер достаточно мощный, то можно
* задать и больше. Данный скрипт ищет максимальное значение, при котором
* хеширование уложится в значение ≤ 350 миллисекундам, что считается приемлемой задержкой
* для систем, которые обрабатывают интерактивные входы.
*/
$timeTarget = 0.350; // 350 миллисекунд

$cost = 8;

do {
$cost++;
$start = microtime(true);
password_hash("test", PASSWORD_BCRYPT, ["cost" => $cost]);
$end = microtime(true);
} while ((
$end - $start) < $timeTarget);

echo
"Оптимальная стоимость: " . $cost;

?>

Вывод приведённого примера будет похож на:

Оптимальная стоимость: 12

Пример #4 Пример использования функции password_hash() с алгоритмом Argon2i

<?php

echo 'Хеш Argon2i: ' . password_hash('rasmuslerdorf', PASSWORD_ARGON2I);

?>

Вывод приведённого примера будет похож на:

Хеш Argon2i: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0

Примечания

Предостережение

Настоятельно рекомендуется использовать автоматическую генерацию соли. Данная функция самостоятельно создаст хорошую соль, если вы не будете ей мешать подсовывая свою.

Как было замечено выше, опция salt была объявлена устаревшей в PHP 7.0 и будет вызывать соответствующее предупреждение. Поддержка ручного задания соли была удалена в PHP 8.0.

Замечание:

Рекомендуется протестировать данную функцию на вашем оборудовании для определения оптимального значения алгоритмической сложности. Убедитесь, что с выбранной сложностью функция выполняется быстрее 350 миллисекунд для интерактивных систем. Скрипт в приведённом выше примере поможет выбрать оптимальное значение.

Замечание: Обновление поддерживаемых алгоритмов для этой функции (или изменение значения по умолчанию) обязаны следовать правилам:

  • Любой новый алгоритм должен присутствовать в ядре как минимум 1 полный релиз PHP для того, чтобы его можно было установить по умолчанию. Таким образом, если, к примеру, новый алгоритм был добавлен в 7.5.5, то задать по умолчанию его можно будет только в 7.7 (7.6 будет тем самым полным релизом, в течение которого он должен присутствовать, от 7.6.0 до 7.7.0). Но если новый алгоритм добавлен в 7.6.0, то его также можно будет задать по умолчанию в версии 7.7.0.
  • Алгоритм по умолчанию может быть изменён только в полном релизе (7.3.0, 8.0.0 и т. д.), но не в промежуточных. Единственное исключение — это критическая уязвимость, найденная в текущем алгоритме.

Смотрите также

  • password_verify() - Проверяет, соответствует ли пароль хешу
  • password_needs_rehash() - Проверяет, что указанный хеш соответствует заданным опциям
  • crypt() - Хеширует строку необратимым способом
  • sodium_crypto_pwhash_str() - Получает ASCII-кодированный хеш