Skip to content
Permalink
Browse files

Implement more time constant string comparisons.

Prefer hash_equals if it exists. If not borrow the implementation from
resonantcore/php-future.

Refs #6139
  • Loading branch information...
markstory committed Mar 23, 2015
1 parent 17898ca commit d77a4c1fe29fa535c963881fa773b00124ae24a6
Showing with 26 additions and 1 deletion.
  1. +26 −1 src/Utility/Security.php
@@ -227,14 +227,39 @@ public static function decrypt($cipher, $key, $hmacSalt = null)
$cipher = substr($cipher, $macSize);
$compareHmac = hash_hmac('sha256', $cipher, $key);
if ($hmac !== $compareHmac) {
if (!static::_constantEquals($hmac, $compareHmac)) {
return false;
}
$crypto = static::engine();
return $crypto->decrypt($cipher, $key);
}
/**
* A timing attack resistant comparison that prefers native PHP implementations.
*
* @param string $hmac The hmac from the ciphertext being decrypted.
* @param string $compare The comparison hmac.
* @return bool
* @see https://github.com/resonantcore/php-future/
*/
protected static function _constantEquals($hmac, $compare)
{
if (function_exists('hash_equals')) {
return hash_equals($hmac, $compare);
}
$hashLength = mb_strlen($hmac, '8bit');
$compareLength = mb_strlen($compare, '8bit');
if ($hashLength !== $compareLength) {
return false;
}
$result = 0;
for ($i = 0; $i < $hashLength; $i++) {
$result |= (ord($hmac[$i]) ^ ord($compare[$i]));
}
return $result === 0;
}
/**
* Gets or sets the HMAC salt to be used for encryption/decryption
* routines.

0 comments on commit d77a4c1

Please sign in to comment.
You can’t perform that action at this time.