hash_hkdf()でわざわざバイナリキー/バイナリSaltを使うことに意味はない

(Last Updated On: 2018年8月13日)

PHP 7.1で追加された hash_hkdf() は出鱈目なシグニチャを持っています。バイナリキーを使うことを想定して、わざわざ既存のハッシュ関数とは異なり、バイナリハッシュ値だけを返せるようになっています。

暗号化がプログラム内で完結する、といった極一部の例外を除きhash_hkdf()でわざわざバイナリキーを使う意味はありません。

CSRFキーを守るURLを守るAPIキーを守る、といったWebアプリケーションで最も頻繁に使われる鍵導出ではバイナリキー/バイナリSaltは、遅いのでむしろ有害と言えます。わざわざバイナリを使う必要はありません。

参考: HMACハッシュの使い方のまとめ – HAMCですが、HKDFはHMAC based Key Derivation Functionです。多くがHKDFで置き換えられます。HKDFが使える場合、hash_hkdf()を使った方が速くなるでしょう。これはPHPの関数呼び出しのオーバーヘッドが比較的大きいことに起因します。

テストコード

<?php

$key = bin2hex(random_bytes(32));
$salt = bin2hex(random_bytes(32));
$lim = 1000000;


$start = microtime(true);
for($i=0; $i<$lim; $i++) {
    hash_hkdf('sha256', $key, 0, null, $salt);
}
echo 'HEX: '. (microtime(true) - $start) . PHP_EOL;

$start = microtime(true);
for($i=0; $i<$lim; $i++) {
    hash_hkdf('sha256', hex2bin($key), 0, null, hex2bin($salt));
}
echo 'BIN: '. (microtime(true) - $start) . PHP_EOL;

このテストコードでは、最初にHEX、次にバイナリのキー/Saltを使っています。ハッシュ関数の特性として”同じエントロピー”ならハッシュのサイズと同じキーとSalt”を使うと最も性能的に有利かつ最大限の安全性を得られます。(つまり、バイナリの方がハッシュ関数の仕組みとして有利)

C言語ならバイナリのキー/Saltを使った方が速くなる可能性が高いです。しかし、言語が変わると”関数呼び出しオーバーヘッド”が加わります。

テスト結果

[yohgaki@dev 201703]$ php test.php 
HEX: 3.8135788440704
BIN: 4.2421109676361

PHPの場合、HEX値のキー/Saltの方が速いです。

まとめ

コードや設定ファイルにバイナリ値のキーを保存することは出来ません。(できますが、お薦めできません)テキストインターフェースが中心のWebではSaltをバイナリで渡す事もできません。キーやSaltは普通、”テキスト”です。

hash_hkdf()を使う場合、わざわざバイナリ値のキー/Saltを使わずに普通にHEX値を使いましょう。hash_hmac()も同様です。

API設計として一から十までダメなhash_hkdf()ですが、便利な関数なので活用しましょう。

 

投稿者: yohgaki