我只是碰到这种代码在Zend Framework中的HTTP验证图书馆来了。 这似乎是使用一种特殊的字符串比较功能,使之更加安全。 不过,我不太明白的意见。 任何人可以解释为什么这个功能是不是做更安全$a == $b
?
/**
* Securely compare two strings for equality while avoided C level memcmp()
* optimisations capable of leaking timing information useful to an attacker
* attempting to iteratively guess the unknown string (e.g. password) being
* compared against.
*
* @param string $a
* @param string $b
* @return bool
*/
protected function _secureStringCompare($a, $b)
{
if (strlen($a) !== strlen($b)) {
return false;
}
$result = 0;
for ($i = 0; $i < strlen($a); $i++) {
$result |= ord($a[$i]) ^ ord($b[$i]);
}
return $result == 0;
}
它看起来像他们试图阻止攻击时机 。
在密码学中,定时攻击是其中攻击者试图通过分析来执行加密算法所需的时间妥协密码系统侧通道攻击。 在计算机中的每个逻辑操作花费的时间来执行,并且时间可以有所不同基于输入; 用的时间为各操作精确的测量,攻击者可以向后工作到输入端。
基本上,如果它需要不同的时间量来比较正确的密码和密码不正确,那么你可以使用的时间来找出你猜中密码的多少个字符。
考虑一个非常有缺陷的字符串比较(这基本上是正常的字符串相等功能,具有明显的wait
加):
function compare(a, b) {
if(len(a) !== len(b)) {
return false;
}
for(i = 0; i < len(a); ++i) {
if(a[i] !== b[i]) {
return false;
}
wait(10); // wait 10 ms
}
return true;
}
说你给一个密码,它(始终)需要一定的时间为一个密码,然后再另外约10毫秒。 这是什么告诉你吗? 这意味着第二个密码有一个或多个字符比第一个是正确的。
这让你做电影的黑客 - 在这里你想在同一时间(比猜测每一个可能的密码容易得多)的密码一个字符。
在现实世界中,还有其他因素参与,所以你必须尝试密码很多很多次来处理现实世界的随机性,但你仍然可以尝试每一个字符的密码,直到一个显然需要更长的时间,然后开始在两个字符的密码,等等。
此功能还在这里有一个小问题:
if(strlen($a) !== strlen($b)) {
return false;
}
它可以让你使用攻击时机找出密码,它可以让你不打扰任何猜测或长或短的密码的正确长度。 在一般情况下, 你要散列你的密码第一(这将创造平等的长字符串),所以我猜他们不认为这是一个问题。