(PHP 5 >= 5.6.0, PHP 7, PHP 8)
hash_equals — タイミング攻撃に対しても安全な文字列比較
$known_string
, #[\SensitiveParameter] string $user_string
): bool
実行している間に known_string
の内容を漏らすことなく、
ふたつの文字列が等しいかどうかを調べます。
この関数は、タイミング攻撃を緩和する目的で使えます。
===
を用いた通常の比較は、値が異なるかどうかや、
値が最初に異なる位置に応じて、比較に多少時間がかかります。
よって、その間に秘密の known_string
の内容が漏洩してしまいます。
最初のパラメータよりはむしろ、 2つ目の文字列をユーザーが指定することが重要です。
known_string
秘密にしておく必要がある、既知の文字列
user_string
ユーザーが指定する、比較対象の文字列
例1 hash_equals() の例
<?php
$secretKey = '8uRhAeH89naXfFXKGOEj';
// $value と $signature の値はユーザが提供します。
// 例: URL内の値と、$_GET から取得した値です
$value = 'username=rasmuslerdorf';
$signature = '8c35009d3b50caf7f5d2c1e031842e6b7823a1bb781d33c5237cd27b57b5f327';
if (hash_equals(hash_hmac('sha256', $value, $secretKey), $signature)) {
echo "The value is correctly signed.", PHP_EOL;
} else {
echo "The value was tampered with.", PHP_EOL;
}
?>
上の例の出力は以下となります。
The value is correctly signed.
注意:
指定するパラメータは両方、長さが等しくなければいけません。 違う長さの文字列が指定されると、この関数はすぐに
false
を返すので、 タイミング攻撃が行われた場合に既知の文字列の長さが漏洩するかもしれません。