note 115664 added to function.hash-equals

From: Date: Thu, 04 Sep 2014 21:46:26 +0000
Subject: note 115664 added to function.hash-equals
Groups: php.notes 
Request: Send a blank email to php-notes+get-200368@lists.php.net to get a copy of this message
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; } } ?> ---- Server IP: 72.52.91.14 Probable Submitter: 77.187.66.68 ---- Manual Page -- http://php.net/manual/en/function.hash-equals.php Edit -- https://master.php.net/note/edit/115664 Del: integrated -- https://master.php.net/note/delete/115664/integrated Del: useless -- https://master.php.net/note/delete/115664/useless Del: bad code -- https://master.php.net/note/delete/115664/bad+code Del: spam -- https://master.php.net/note/delete/115664/spam Del: non-english -- https://master.php.net/note/delete/115664/non-english Del: in docs -- https://master.php.net/note/delete/115664/in+docs Del: other reasons-- https://master.php.net/note/delete/115664 Reject -- https://master.php.net/note/reject/115664 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#200368) next »