hash_equals
Timing attack safe string comparison
Description
bool hash_equals(#[\SensitiveParameter]string $known_string
, #[\SensitiveParameter]string $user_string
)
This function can be used to mitigate timing attacks. Performing a regular
comparison with ===
will take more or less time to execute
depending on whether the two values are different or not and at which
position the first difference can be found, thus leaking information about
the contents of the secret known_string
.
Caution
It is important to provide the user-supplied string as the second
parameter, rather than the first.
Parameters
-
known_string
-
The known string that must be kept secret.
-
user_string
-
The user-supplied string to compare against.
Return Values
Returns true
when the two strings are equal, false
otherwise.
Examples
Example #1 hash_equals example
<?php
$secretKey = '8uRhAeH89naXfFXKGOEj';
// Value and signature are provided by the user, e.g. within the URL
// and retrieved using $_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 above example will output:
The value is correctly signed.
Notes
Note:
Both arguments must be of the same length to be compared successfully.
When arguments of differing length are supplied, false
is returned immediately and
the length of the known string may be leaked in case of a timing attack.