Skip to content

Commit

Permalink
Implement more time constant string comparisons.
Browse files Browse the repository at this point in the history
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 d77a4c1
Showing 1 changed file with 26 additions and 1 deletion.
27 changes: 26 additions & 1 deletion src/Utility/Security.php
Expand Up @@ -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.
Expand Down

0 comments on commit d77a4c1

Please sign in to comment.