Skip to content

Instantly share code, notes, and snippets.

@phayes
Created April 14, 2016 20:36
Show Gist options
  • Save phayes/36ae26d7a74d13cf77b1c2e0a8380638 to your computer and use it in GitHub Desktop.
Save phayes/36ae26d7a74d13cf77b1c2e0a8380638 to your computer and use it in GitHub Desktop.
/**
* A timing safe equals comparison
*
* From: http://blog.ircmaxell.com/2012/12/seven-ways-to-screw-up-bcrypt.html
*
* To prevent leaking length information, it is important
* that user input is always used as the second parameter.
*
* @param string $safe The internal (safe) value to be checked
* @param string $user The user submitted (unsafe) value
*
* @return boolean True if the two strings are identical.
*/
function time_safe_equals($safe, $user) {
// Prevent issues if string length is 0
$safe .= chr(0);
$user .= chr(0);
$safeLen = strlen($safe);
$userLen = strlen($user);
// Set the result to the difference between the lengths
$result = $safeLen - $userLen;
// Note that we ALWAYS iterate over the user-supplied length
// This is to prevent leaking length information
for ($i = 0; $i < $userLen; $i++) {
// Using % here is a trick to prevent notices
// It's safe, since if the lengths are different
// $result is already non-0
$result |= (ord($safe[$i % $safeLen]) ^ ord($user[$i]));
}
// They are only identical strings if $result is exactly 0...
return $result === 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment