はじめに
PHPでの実装にて、ユーザ情報のパスワードのソルト(パスワードに付与するランダムな文字列)を作成し、password_hash
関数に渡してハッシュ化しようとしたら問題が起きました。
その際にPHPでのハッシュ化について少し調べましたので記述します。
password_hash()
の動作
password_hash
はPHP5.5以降で使うことができ、強力な一方向ハッシュアルゴリズムを使って、 新しいパスワードハッシュを作るハッシュ関数です。
option
引数でソルトを設定可能ですが、指定しない場合はランダムソルトを使い、同じパスワードの文字列であっても毎回違うハッシュ値を生成します。
しかし、PHP7からoption
でのソルトは非推奨、PHP8からはソルトが設定されていても無視されてランダムソルトが使用されるので注意が必要です(これが原因でsymfonyをdevelopモードで動かしていて発生するとエラー画面でWarningが表示されてしまいます)。
PHPバージョン7 ソルトを設定してpassword_hash
実行 – 常に同じハッシュ値が出力
$ php -r 'echo password_hash("password1234", PASSWORD_DEFAULT, ["salt" => "12345678abcdefghijklmnopqr"]) . "\n";'
PHP Warning: Module 'intl' already loaded in Unknown on line 0
$2y$10$12345678abcdefghijklmeM.7oow2Y4W4fvf6l8tqDLqrbNMfGcUu
$ php -r 'echo password_hash("password1234", PASSWORD_DEFAULT, ["salt" => "12345678abcdefghijklmnopqr"]) . "\n";'
PHP Warning: Module 'intl' already loaded in Unknown on line 0
$2y$10$12345678abcdefghijklmeM.7oow2Y4W4fvf6l8tqDLqrbNMfGcUu
PHPバージョン8 ソルトを設定してpassword_hash
実行 – 実行ごとに別のハッシュ値を出力
$ php -r 'echo password_hash("password1234", PASSWORD_DEFAULT, ["salt" => "salt5678"]) . "\n";'
Warning: password_hash(): The "salt" option has been ignored, since providing a custom salt is no longer supported in Command line code on line 1
$2y$10$xuEN9kuzf82XmezQJZcgYeuRGSiuxZZG1YXVKEm2jekols.2zuFAW
$ php -r 'echo password_hash("password1234", PASSWORD_DEFAULT, ["salt" => "salt5678"]) . "\n";'
Warning: password_hash(): The "salt" option has been ignored, since providing a custom salt is no longer supported in Command line code on line 1
$2y$10$8so0XQSyDR2vZmZ5ZFuADu0GLll7oLPG29n.qKekLidC1ciKjIfN.
password_verify()
によるハッシュ値の照合
ランダムソルトで毎回違うハッシュ値が出力されますが、以下のpassword_verify
関数を使うことで照合可能です。
検証用プログラムpassword_test – パスワードのハッシュ化とpassword_verify
による照合結果の出力
<?php
$passwd = "password1234";
$passwd_hash = password_hash($passwd,PASSWORD_DEFAULT);
echo $passwd_hash . "\n";
if (password_verify($passwd,$passwd_hash))
{
echo "一致しました。\n";
}
else
{
echo "一致してません。\n";
}
?>
password_test実行例 – ハッシュ値は実行ごとに違うが、照合結果は常に一致
$ php password_test.php
$2y$10$hQO3UzdlqhmR4jFL5HAWq.oUjplDCPrdZ26QoubfRpuLMbIZ0yjf.
一致しました。
$ php password_test.php
$2y$10$FzdrodqV3RC1qtVK/fI7WeheOkztdHMdEjDBQlBZEfys09o4v3gc6
一致しました。
$ php password_test.php
$2y$10$xYgQVmjmy0bnFugxgpEOr.8YcDxuY1DHxG/Ua9/rgXo6NuPaKU5Su
一致しました。
まとめ
PHP8以降でpassword_hash
を使ってパスワードの管理を行う場合はソルトの生成は不要となります。
そのため、パスワードのハッシュ値をDBに保存し、照合する場合はpassword_verify
を使用するようにしましょう。