関数の概要
hash_equalsは、PHPで2つの文字列を比較するための関数です。この関数は主にセキュリティ目的で使われ、タイミング攻撃(Timing Attack)に耐性のある比較を実現します。通常の文字列比較は比較処理が途中で終わる場合があり、攻撃者が処理時間の違いから情報を推測できるリスクがありますが、hash_equalsは比較処理の時間を一定に保つため、そのようなリスクを低減します。
パラメータの説明
known_string(string): 既知の安全な文字列。ハッシュ値などの正しい値を指定します。user_string(string): 比較対象の文字列。ユーザーから入力された値や検証したい値を指定します。
戻り値
hash_equalsは、2つの文字列が完全に一致していれば true を返し、そうでなければ false を返します。長さが異なる場合も false になります。
使用例
基本的な使い方
<?php
$hash1 = hash('sha256', 'password123');
$hash2 = hash('sha256', 'password123');
if (hash_equals($hash1, $hash2)) {
echo "一致しました。";
} else {
echo "一致しません。";
}
?>
この例では、同じ文字列をSHA-256でハッシュ化し、hash_equalsで比較しています。等しい場合に「一致しました。」と表示されます。
ユーザー入力の認証処理で使う例
<?php
$stored_hash = '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd2f38...'; // パスワードのハッシュ(実際は完全な値)
$user_input = $_POST['password'];
$user_hash = hash('sha256', $user_input);
if (hash_equals($stored_hash, $user_hash)) {
echo "ログイン成功";
} else {
echo "パスワードが違います";
}
?>
ユーザーの入力したパスワードのハッシュと、保存しているハッシュを hash_equals で比較し安全に検証しています。
APIのトークン検証で使う例
<?php
$valid_token = 'abcdef1234567890';
$provided_token = $_SERVER['HTTP_AUTHORIZATION'];
if (hash_equals($valid_token, $provided_token)) {
echo "認証成功";
} else {
header('HTTP/1.1 401 Unauthorized');
exit;
}
?>
APIリクエストの認証トークンを、タイミング攻撃に強い方法で比較する例です。
関連する関数
hash: ハッシュ値を生成する関数。hash_equalsと組み合わせて使います。strcmp: 通常の文字列比較を行いますが、タイミング攻撃に弱いです。hash_hmac: HMACによるハッシュを生成して安全性を高める場合に使用します。
まとめ
hash_equalsは、セキュリティ上重要な文字列比較を安全に行いたい場合に欠かせない関数です。特にパスワード認証やAPIトークンの検証時に使うことで、タイミング攻撃のリスクを軽減できます。通常の比較関数よりも堅牢な比較を行うため、実務のセキュリティ対策として積極的に利用しましょう。
