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()