10

在学习密码哈希并保存在数据库中时,我发现了这篇文章:https ://crackstation.net/hashing-security.htm#phpsourcecode

一切都很清楚,除了这个我不明白为什么不使用正常相等的函数?这意味着什么:在长度恒定的时间内比较两个字符串 $a 和 $b。

// Compares two strings $a and $b in length-constant time.
function slow_equals($a, $b)
{
    $diff = strlen($a) ^ strlen($b);
    for($i = 0; $i < strlen($a) && $i < strlen($b); $i++)
    {
        $diff |= ord($a[$i]) ^ ord($b[$i]);
    }
    return $diff === 0;
}
4

1 回答 1

27

当您通常比较两个字符串是否相等时,如果遇到第一个不相等,算法就会停止。

像这样:“aaa” == “aba”?第一个字符?两个“一”。第二个字符?“a”不是“b”,所以在这里停下来节省时间。不比较最后一个字符。

在比较与安全相关的字符串时,攻击者可能会因为此类比较函数的运行时间而获知哪个字符是正确的,哪个是错误的。

考虑一下使用纯文本密码的不安全做法。如果攻击者可以通过测量密码比较运行的时间来确定他猜出的密码的第一个字符是否正确,那么他只需要大约 62 次猜测(大小写字母和数字)就可以知道第一个字母。一个字母的运行时间更长,因为第一个字母与真实密码相同,然后比较了第二个字母。现在第二个字母被迭代了。并且经过 62 次以上的猜测,就知道了。

这大大削弱了安全性,因为在不知道第一个字母是否正确的情况下,您需要 62*62 次猜测两个字母的密码。有了线索,你只需要 62 + 62 次猜测。

一个长度常数比较函数比较所有的字母,只有在最后才显示字符串是否匹配。这样你就无法知道哪个字母是正确的。

散列字符串会混淆一些东西,但是因为你不知道攻击者是否预先生成了一堆散列,或者正在动态生成它们,并且如果散列不匹配,则不会暴力破解相应的密码,你这样做不希望任何人知道哈希不匹配的位置。这是一个小的附加安全组件,但非常重要。

于 2013-09-15T08:53:58.450 回答