password_hash

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

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

Описание

password_hash(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. Генерирует стандартный хеш, совместимый с генерированным функцией crypt() с использованием идентификатора "$2y$". В результате будет сгенерирована строка длиной 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.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
/**
* Данный код замерит скорость выполнения операции хеширования для вашего сервера
* с разными значениями алгоритмической сложности для определения максимального
* его значения, не приводящего к деградации производительности. Хорошее базовое
* значение лежит в диапазоне 8-10, но если ваш сервер достаточно мощный, то можно
* задать и больше. Данный скрипт ищет максимальное значение, при котором
* хеширование уложится в 50 миллисекунд.
*/
$timeTarget = 0.05; // 50 миллисекунд.

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

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

Результатом выполнения данного примера будет что-то подобное:

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

Пример #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 и будет вызывать соответствующее предупреждение. Поддержка ручного задания соли может быть удалена в более новых версиях.

Замечание:

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

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

  • Любой новый алгоритм должен присутствовать в ядре как минимум 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-кодированный хеш