note 115664 deleted from function.hash-equals by cmb

From: Date: Thu, 29 Jul 2021 12:42:14 +0000
Subject: note 115664 deleted from function.hash-equals by cmb
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-216684@lists.php.net to get a copy of this message
Note Submitter: Markus P. N. ---- I don't know why asphp at dsgml dot com got that many downvotes, the function seems to work. I extended it a bit to support strings of diffent length and to handle errors and ran some tests: The test results and how to reproduce them: http://pastebin.com/mLMXJeva The function: <?php if (!function_exists('hash_equals')) { /** * Timing attack safe string comparison * * Compares two strings using the same time whether they're equal or not. * This function should be used to mitigate timing attacks; for instance, when testing crypt() password hashes. * * @param string $known_string The string of known length to compare against * @param string $user_string The user-supplied string * @return boolean Returns TRUE when the two strings are equal, FALSE otherwise. */ function hash_equals($known_string, $user_string) { if (func_num_args() !== 2) { // handle wrong parameter count as the native implentation trigger_error('hash_equals() expects exactly 2 parameters, ' . func_num_args() . ' given', E_USER_WARNING); return null; } if (is_string($known_string) !== true) { trigger_error('hash_equals(): Expected known_string to be a string, ' . gettype($known_string) . ' given', E_USER_WARNING); return false; } $known_string_len = strlen($known_string); $user_string_type_error = 'hash_equals(): Expected user_string to be a string, ' . gettype($user_string) . ' given'; // prepare wrong type error message now to reduce the impact of string concatenation and the gettype call if (is_string($user_string) !== true) { trigger_error($user_string_type_error, E_USER_WARNING); // prevention of timing attacks might be still possible if we handle $user_string as a string of diffent length (the trigger_error() call increases the execution time a bit) $user_string_len = strlen($user_string); $user_string_len = $known_string_len + 1; } else { $user_string_len = $known_string_len + 1; $user_string_len = strlen($user_string); } if ($known_string_len !== $user_string_len) { $res = $known_string ^ $known_string; // use $known_string instead of $user_string to handle strings of diffrent length. $ret = 1; // set $ret to 1 to make sure false is returned } else { $res = $known_string ^ $user_string; $ret = 0; } for ($i = strlen($res) - 1; $i >= 0; $i--) { $ret |= ord($res[$i]); } return $ret === 0; } } ?>

« previous php.notes (#216684) next »