sodium_crypto_pwhash

(PHP 7 >= 7.2.0, PHP 8)

sodium_crypto_pwhashПолучает ключ из пароля, используя Argon2

Описание

sodium_crypto_pwhash(
    int $length,
    string $password,
    string $salt,
    int $opslimit,
    int $memlimit,
    int $algo = SODIUM_CRYPTO_PWHASH_ALG_DEFAULT
): string

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

Распространённая причина использования этой конкретной функции - получить начальные числа для криптографических ключей из пароля и соли, а затем использовать эти начальные числа для генерации фактических ключей, необходимых для некоторых целей (например, sodium_crypto_sign_detached()).

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

length

int; Длина создаваемого хеша пароля в байтах.

password

string; Пароль, для которого создаётся хеш.

salt

Соль, которую нужно добавить к паролю перед хешированием. Соль должна быть непредсказуемой, в идеале генерируемой из хорошего источника случайных чисел, такого как random_bytes(), а также быть длиной не меньше байт, указанных в константе SODIUM_CRYPTO_PWHASH_SALTBYTES.

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.

algo

int Число, указывающее используемый алгоритм хеширования. По умолчанию задана SODIUM_CRYPTO_PWHASH_ALG_DEFAULT (рекомендуемый в настоящее время алгоритм, который может быть изменён с при смене версии libsodium на другую), или явно используя константу SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13, представляющую версию алгоритма Argon2id 1.3.

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

Возвращает захешированный пароль. Возвращаемое значение является бинарной строкой, а не ASCII-представлением и не содержит никакой дополнительной информации о параметрах, с которыми генерировался хеш. Таким образом вам необходимо самим сохранять значения использованных параметров для проверки корректности хеша в будущем. Чтобы всем этим не заниматься - используйте функцию sodium_crypto_pwhash_str().

Примеры

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

<?php
//Для дальнейшенй проверки необходимо сохранить соль
$salt = random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES);
// Используем bin2hex для удобочитаемости
echo bin2hex(
sodium_crypto_pwhash(
16, // == 128 бит
'password',
$salt,
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13
)
);
?>

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

a18f346ba57992eb7e4ae6abf3fd30ee

add a note add a note

User Contributed Notes 1 note

up
-8
craig at craigfrancis dot co dot uk
4 years ago
When encrypting, you would ideally use a randomly generated key, as that's considerably harder to guess.

For example, sodium_crypto_aead_chacha20poly1305_ietf_keygen()

But if you need to use a password to encrypt/decrypt, you can use sodium_crypto_pwhash():

<?php

function secrets_encrypt($password, $secret) {

 
$config = [
     
'size'      => SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES,
     
'salt'      => random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES),
     
'limit_ops' => SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE,
     
'limit_mem' => SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE,
     
'alg'       => SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13,
     
'nonce'     => random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES),
    ];

 
// $config['limit_ops'] = SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE;
  // $config['limit_mem'] = SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE;

 
$key = sodium_crypto_pwhash(
     
$config['size'],
     
$password,
     
$config['salt'],
     
$config['limit_ops'],
     
$config['limit_mem'],
     
$config['alg'],
    );

 
$encrypted = sodium_crypto_aead_chacha20poly1305_ietf_encrypt(
     
$secret,
     
$config['nonce'], // Associated Data
     
$config['nonce'],
     
$key
   
);

  return [
     
'config' => array_map('base64_encode', $config),
     
'encrypted' => base64_encode($encrypted),
    ];

}

$password = 'YoxPR4QLeZ';
$secret   = 'This-is-my-secret';

$data = secrets_encrypt($password, $secret);

?>

To decrypt with that password, using the same limits:

<?php

function secrets_decrypt($password, $data) {

 
$config = array_map('base64_decode', $data['config']);
 
$encrypted = base64_decode($data['encrypted']);

 
$key = sodium_crypto_pwhash(
     
$config['size'],
     
$password,
     
$config['salt'],
     
$config['limit_ops'],
     
$config['limit_mem'],
     
$config['alg'],
    );

  return
sodium_crypto_aead_chacha20poly1305_ietf_decrypt(
     
$encrypted,
     
$config['nonce'], // Associated Data
     
$config['nonce'],
     
$key
   
);

}

$secret = secrets_decrypt($password, $data);

?>
To Top