hash_equals
hash_equals($known_string, $user_string)
Returns true when both strings are the same. The comparison takes the same time regardless of where the strings differ, so nothing can be deduced from the response time.
Parameters
- $known_string – the correct value (stored, calculated on the server).
- $user_string – the value from the user.
Examples
$token = "a3f9c2e81b7d4f60";
var_dump(hash_equals($token, "a3f9c2e81b7d4f60")); // bool(true)
var_dump(hash_equals($token, "a3f9c2e81b7d4f61")); // bool(false)
// verifying a CSRF token from a form
// in practice $_SESSION["csrf"] and $_POST["csrf"]
$token_in_session = "a3f9c2e81b7d4f60";
$from_form = "a3f9c2e81b7d4f60";
var_dump(is_string($from_form) && hash_equals($token_in_session, $from_form)); // bool(true)
// a value from a form can be an array – check the type first
$from_form = array("x");
var_dump(is_string($from_form) && hash_equals($token_in_session, $from_form)); // bool(false)
Things to watch out for
- Both parameters must be strings. Another type means a warning and false in PHP 7, a TypeError exception from PHP 8.0. Therefore check user input with is_string() first.
- The order of the parameters matters: the first is the correct value, the second the submitted one.
- Do not compare passwords directly, not even with this function, password_verify() verifies them.
- Strings of different lengths return false immediately. The length of the secret value may thus be revealed, but that does not matter for tokens of a fixed length.
Related functions:
hash_hmac()
password_verify()
hash()