PHP Velho Oeste 2024

sodium_crypto_pwhash

(PHP 7 >= 7.2.0, PHP 8)

sodium_crypto_pwhashArgon2 アルゴリズムを使い、パスワードからキーを導出する

説明

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

この関数は、 libsodium の crypto_pwhash 派生関数への低レベルのアクセスを提供します。 この関数を使う明確な理由がなければ、 sodium_crypto_pwhash_str()password_hash() 関数を代わりに使うべきです。

この関数を使う共通の理由は、 パスワードとソルトから暗号化キーのためのシードを導出し、 その値を使うことで、特定の目的 (たとえば、sodium_crypto_sign_detached()) で使う実際の鍵を生成することです。

パラメータ

length

生成するパスワードハッシュの長さ。 バイト単位で指定します。

password

ハッシュを生成するパスワードを文字列で指定します。

salt

ハッシュ化する前に、 パスワードに追加するソルト値。 この値は予測されてはいけません。 random_bytes() のような良質な乱数のソースから生成されることが理想です。 そして、少なくとも長さが SODIUM_CRYPTO_PWHASH_SALTBYTES バイトである必要があります。

opslimit

実際に行う計算処理の最大量。 この値を大きくすると、 キーを計算するのに必要なCPUサイクルが増加します。 意図した使い方次第で、 適切な値の上限値を設定するために、いくつかの定数が存在します。 弱いものから強いものへと並べると、以下のとおりです: 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

使用するハッシュアルゴリズムのIDを指定します。 デフォルトは、 SODIUM_CRYPTO_PWHASH_ALG_DEFAULT (現状推奨されるアルゴリズム。 これは、libsodium のバージョンによって変更されるかもしれません) です。 または、 Argon2id アルゴリズム version 1.3 を表す SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13 を明示的に使うこともできます。

戻り値

導出されたキーを返します。 返される値は、ハッシュのバイナリ文字列であり、 ASCII でエンコードされた文字列ではありませんし、 ハッシュを生成するために使われた追加のパラメータも含まれていません。 よって、将来パスワードを検証するためには、 それらの情報を保持しておく必要があります。 そうなることを避けるために、 sodium_crypto_pwhash_str() を使って下さい。

例1 sodium_crypto_pwhash() の例

<?php
//Need to keep the salt if we're ever going to be able to check this password
$salt = random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES);
//Using bin2hex to keep output readable
echo bin2hex(
sodium_crypto_pwhash(
16, // == 128 bits
'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