PHP Conference Nagoya 2025

sodium_crypto_pwhash_str

(PHP 7 >= 7.2.0, PHP 8)

sodium_crypto_pwhash_strПолучает ASCII-кодированный хеш

Описание

sodium_crypto_pwhash_str(#[\SensitiveParameter] string $password, int $opslimit, int $memlimit): string

Функция использует ресурсоёмкий по ЦПУ и памяти алгоритм хешированияа, а также случайно сгенерированную соль и ограничения по памяти и процессору для генерации хэша в кодировке ASCII, который подходит для хранения паролей.

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

password

Строка (string); пароль, для которого функция сгенерирует хеш.

opslimit

Задаёт ограничение на потребление процессорного времени. Увеличение этого числа приведет к тому, что функции потребуется больше циклов ЦП для вычисления ключа. Предел операций на соответствующие значения в зависимости от предполагаемого использования устанавливают константами в порядке силы: SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE и SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE.

memlimit

Максимальный объем оперативной памяти в байтах, которую будет использовать функция. В выборе подходящего значения помогают константы в порядке размера: SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE, SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE и SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE. Обычно константы должны сочетаться со значениями opslimit, которые им соответствуют.

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

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

Чтобы для одного и того же пароля каждый раз генерировался один и тот же хеш, устанавливают одинаковые значения параметров opslimit и memlimit. Поскольку эти параметры функция включает в сгенерированный хеш, функция sodium_crypto_pwhash_str_verify() может проверять его корректность без необходимости хранить эти параметры отдельно.

Примеры

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

<?php

$password
= 'password';

echo
sodium_crypto_pwhash_str(
$password,
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);

?>

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

$argon2id$v=19$m=65536,t=2,p=1$oWIfdaXwWwhVmovOBc2NAQ$EbsZ+JnZyyavkafS0hoc4HdaOB0ILWZESAZ7kVGa+Iw

Примечания

Замечание:

Хеши вычисляются алгоритмом Argon2ID, который устойчив к атакам стороннего канала и GPU. В отличие от функции password_hash(), у этой функции нет параметра salt (он генерируется автоматически), а параметры opslimit и memlimit — обязательные.

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

Добавить

Примечания пользователей 1 note

up
4
marcus at synchromedia dot co dot uk
3 years ago
If you want to ensure that the hashes you generate with sodium_crypto_pwhash_str are compatible with those generated by password_hash, you need to keep an eye on that memory setting. According to the docs, the password_hash memory_cost param is given in "kibibytes", whereas sodium_crypto_pwhash_str uses bytes. I did some experiments to see what the difference is and ran into this:

echo password_hash('password',
PASSWORD_ARGON2ID,
[
'memory_cost' => 15000,
'time_cost' => 26,
'threads' => 1,
];

echo sodium_crypto_pwhash_str(
'password', 26,
15000000);

These result in:
$argon2id$v=19$m=15000,t=26,p=1$VG5MSkhUdEdFaGwyVG5sWA$laRHogIVAnC4ggLI8RdCDWlITTdicrdq0tK6SHGf4CI
$argon2id$v=19$m=14648,t=26,p=1$ClQ37/z9u7K6V1C2bkD4QA$51m8KhQQ9gujFSF+JyQR9d5QesayJiKsFmDU4HnGBHg

Notice that the "m=" numbers are different, and also different from what we asked for. It's down to the "kibibytes" unit. If we multiply the 15000 we used for password_hash by 1,024 instead of 1,000, we get 15,360,000, and using that number gives us the expected hash params:

echo sodium_crypto_pwhash_str(
'password', 26,
15360000);

$argon2id$v=19$m=15000,t=26,p=1$Qz3pWktOvT6X/LvdAk0bgQ$KosSFPfHUtWg+ppyRs3Op5/zIV6F6iy2Q7Gom8wP29c

This should be compatible with password_hash.

Incidentally the numbers I'm using for the Argon2id hash params are taken from the OWASP password guide, which recommend values different from PHP's default: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#argon2id
To Top