PHPでは、ユーザー認証は安全なアプリケーションを構築する際の基本的なリンクです。パスワードまたはトークンを比較すると、安全でない文字列比較方法がタイム攻撃につながり、攻撃者が機密情報を推測できるようになります。 PHPは、そのような攻撃を防ぐために特別に設計された機能HASH_EQUALS()を提供します。
この記事では、Hash_equals()関数を使用して安全なユーザー認証プロセスを実装して、一般的なセキュリティリスクを回避する方法を紹介します。
時間攻撃とは、プログラムを測定することにより、異なる入力文字列に必要な時間の差を測定することにより、パスワードハッシュや認証トークンなどの機密情報を徐々に推測する攻撃者を指します。
従来の文字列比較関数( ==またはSTRCMPなど)は、一致が故障したときにできるだけ早く返され、ストリングの類似性に依存する比較時間を作成し、情報が公開されます。
Hash_equals()は、PHP 5.6以降で提供される関数です。戻り時間の違いによる情報の漏れを避けるために、一定の時間に2つの文字列を比較するように設計されています。
関数プロトタイプ:
bool hash_equals(string $known_string, string $user_string)
$ nown_string :既知の文字列(通常は保存されたハッシュ値)。
$ user_string :ユーザーが入力した文字列(検証する必要がある値)。
2つの文字列が等しい場合はtrueを返し、それ以外の場合はfalseを返します。
ユーザーが登録すると、パスワードがハッシュされ、セキュリティアルゴリズムを使用して保存されているとします。ログインするときは、ユーザーが入力したパスワードを確認する必要があります。
サンプルコード:
<?php
// ユーザー登録時,データベースにパスワードハッシュを保存します
$password = 'user_password123';
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
// ユーザーがログインするとき,パスワードを確認します
$input_password = $_POST['password'] ?? '';
// パスワードを確認します
if (password_verify($input_password, $hashed_password)) {
// データベースに保存されたハッシュ文字列を取り出します
$stored_hash = $hashed_password;
// 比較のためにユーザーのパスワードを再ハッシュします(ここでのデモンストレーションシナリオは、検証トークンとその他の状況です)
$input_hash = hash('sha256', $input_password);
// 使用 hash_equals 一定の時間比較
if (hash_equals($stored_hash, $input_hash)) {
echo "成功した認証";
} else {
echo "認証に失敗しました";
}
} else {
echo "認証に失敗しました";
}
?>
注:上記の例では、 password_verify()自体がパスワードハッシュを安全に検証し、 hash_equals()はAPIトークンまたはカスタムハッシュ値を確認するシナリオに適しています。
多くのシナリオでは、ユーザーによって渡されたAPIトークンがサーバーに保存されているトークンと一致するかどうかを確認する必要があります。 ==直接使用すると、時間攻撃のリスクがあります。
例:
<?php
// サーバー側のストレージAPIトークン
$stored_token = 'abc123def456';
// 用户提交的トークン
$provided_token = $_GET['token'] ?? '';
// 安全な比較をしてください
if (hash_equals($stored_token, $provided_token)) {
echo "トークン验证通过";
} else {
echo "トークン验证失败";
}
?>
このように、トークンが一致しなくても、攻撃者は時間のかかるプロセスを比較することで正しいトークンを推測することはできません。
Hash_equals()は、時間攻撃を防ぐ一定の時間文字列比較を提供します。
パスワード検証では、 password_hash()およびpassword_verify()を使用することをお勧めします。Hash_equals ()は、トークンまたはハッシュ値の安全な比較に適しています。
Hash_equals()を合理的に使用することにより、認証プロセスのセキュリティを大幅に改善し、機密情報漏れのリスクを減らすことができます。
PHPセキュリティ認証のベストプラクティスについて詳しく知りたい場合は、 https://gitbox.net/php-securityにアクセスしてください。