Table of Contents

HKDFハッシュ値取得には必ずsaltを利用する

HKDF(HMAC based Key Derivation Function)のハッシュ値を取得するhash_hkdf()を利用する場合、salt引数がどうしても利用できない場合を除き、必ず指定する。

salt引数は秘密または非秘密のランダム値をとる。

導出鍵を生成する鍵情報が弱い鍵の場合でも、saltが秘密かつ強い値(=十分なにランダムな値)であれば安全な導を導出できる。

導出鍵を生成する鍵情報が強い鍵の場合、saltが非秘密の弱い値(例:microtime()などの値)は導出鍵の安全性を飛躍的に向上させる。

hash_hkdf()を利用する場合、salt引数とinfo引数の両方を必ず指定する。salt引数またはinfo引数のどちらかしか必要無い場合、hash_hmac()で代用でき、こちらの方が高速である。salt引数もinfo引数も必要ない場合、hash()で代用でき、こちらの方が高速である。

非適合コード例

$ikm = 'MyPassword'; // 弱い鍵
$new_key = hash_hkdf('sha2-256', $ikm);

hash_hkdf()は自動的に安全な鍵を導出しない。このコードは非常に危険な導出鍵を生成する。このような使い方をしてはならない。

適合コード例

$ikm = 'MyPassword'; // 弱い鍵
$salt = random_bytes(32); // 秘密の強い鍵。後で同じ導出鍵を生成できるようどこかに保存する
$new_key = bin2hex(hash_hkdf('sha2-256', $ikm, 0, '', $salt));

上記の適合コードは安全ではあるが、効率的ではない。info引数がないのでhash_hmac()で代用できる。

$ikm = 'MyPassword'; // 弱い鍵
$salt = random_bytes(32); // 秘密の強い鍵。後で同じ導出鍵を生成できるようどこかに保存する
$new_key = hash_hmac('sha2-256', $ikm, $salt);

HKDFはHMACを複数回適用するので、hash_hmac()を使用した方が合理的である。

hash_hkdf()が適切なケースは以下のようなケースとなる。

$ikm = 'MyPassword'; // 弱い鍵
$salt = random_bytes(32); // 秘密の強い鍵。後で同じ導出鍵を生成できるようどこかに保存する
$info = 'admin'; // 導出鍵のコンテクスト 
$new_key = bin2hex(hash_hkdf('sha2-256', $ikm, 0, $info, $salt));

例外

脆弱なHKDFの利用方法のソフトウェアと連携する場合、salt引数を省略せざるを得ない。

リスク評価

[ルール/推奨事項のリスク評価]

[評価例 - 英語表記に統一]

Rule Severity Likelihood Remediation Cost Priority Level
IDS05-J medium unlikely medium P4 L3

関連ガイドライン

参考文献