はじめに
この記事の対象はPHPを使ったシステムを使っている方向けの内容となります。
社内システムを1年くらい前にPHP8.2にアップデートしました。
直近まで「SHA-512」アルゴリズムによるハッシュ化は「hash関数」を利用していました。
しかし、セキュリティ対策を目的として「password_hash関数」を利用するように変更しました。
password_hash関数に変更をしたものの、問題が発生したためこの記事を残すことにします。
発生した問題
password_hash関数が、大量データを一気にハッシュ化するようなシステムには適していなかった
ということです。
社内システムには、1度に5,000件〜10,000件程度のデータをCSVインポートする機能があります。
この機能がhash関数を使っていたときは問題がなかったが、タイムアウトを起こすようになってしまったのです。
どこに原因があるのか調べてみたところ、hash関数とpassword_hash関数のパフォーマンスの違いが原因でした。
実際に、以下のプログラムを作ってパフォーマンスを計測してみました。
計測プログラム
$password = 'aaaaaaaaaaaaaaaaaa';
echo '------ hash関数 -----' . PHP_EOL;
$start_time = microtime(true);
$hashedPasswordSha512 = hash('sha512', $password);
echo "SHA-512 Hash: " . $hashedPasswordSha512 . PHP_EOL;
$end_time = microtime(true);
echo 'execute time: ' . ($end_time - $start_time) . PHP_EOL;
echo PHP_EOL;
echo '------ password_hash関数 --------' . PHP_EOL;
$start_time = microtime(true);
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
echo "Password Hash: " . $hashedPassword . PHP_EOL;
$end_time = microtime(true);
echo 'execute time: ' . ($end_time - $start_time) . PHP_EOL;
計測結果
- hash関数: 1.3E-5秒
- password_hash関数: 0.05秒
考察
hash関数のほうがpassword_hash関数の「100倍」程度高いパフォーマンスを出すことがわかりました。
つまり社内システムでインポートするデータ数が5,000件として、
処理が完了するのにかかる時間はそれぞれ
- hash関数: 0.065秒
- password_hash関数: 250秒
ということになります。
これではpassword_hash関数を利用した場合は、タイムアウトするのも当然ですね。
さいごに
password_hash関数は同じ文字列を何度ハッシュ化しても絶対に同じハッシュ値とならないなど、セキュリティ面で優れており、かつpassword_verify関数なども合わせて利用することができるため、非常に便利であることに変わりはありません。
みなさんもpassword_hash関数を利用する際は気をつけてほしいとおもいます。