使用按位运算符测试SHA-256摘要的相等性

时间:2017-04-05 14:25:57

标签: php node.js sha256

我在nodeJS app中实现令牌系统,我需要检查使用SHA256进行哈希处理的两个字符串的相等性。我最初的想法是我可以使用严格相等的运算符(hash1 === hash2)简单地测试相等性,因为如果它们具有相同的输入,则摘要应该产生相同的字符串。但是,我已经看到Paragon Initiative的一篇文章声称在每个字符的ascii代码上使用按位运算符比较字符串会更安全。

为了比较摘要令牌,Paragon代码使用以下代码片段(PHP):

public static function hash_equals($hash1, $hash2)
    ...

    $res = 0;
    $len = \strlen($hash1);
    for ($i = 0; $i < $len; ++$i) {
        $res |= \ord($hash1[$i]) ^ \ord($hash2[$i]);
    }
    return $res === 0;
}

基本上,每个索引处的字符使用按位XOR,然后使用按位OR保存到标志值。如果任何字符不匹配,则差异将保存在$res

这比使用严格的字符串比较更有效吗?哈希摘要只是字符串,我不知道为什么简单的字符串比较效果不如显式检查字符串中的每个字节。

文章参考:https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence 代码参考:https://github.com/psecio/gatekeeper/blob/7b8ec374e208148692316a34c1b4700d5407ef9b/src/Psecio/Gatekeeper/Gatekeeper.php

更新

我调查了它,npm上的scmp工具可以用于Javascript中的常量字符串比较。

截至2017年4月5日,根据nspsnyk工具,它没有漏洞。

2 个答案:

答案 0 :(得分:2)

修改:Use built in hash_equals in PHP for timing attack resistant compares. 请参阅下面的hash_equals PHP doc.说明。

你不应该使用字符串比较来测试哈希值的原因是它们经过优化,只要它们能够判断字符串是否相等就会返回。

在普通代码中,这是一件好事。您希望尽快得到结果。但是,当谈到安全性时,这会泄漏信息。

如果攻击者反复提交不同的字符串并能够测量他被拒绝访问之前的时间差异,他可以使用它作为一种方法来确定他正确猜到的子字符串的数量。

有关详细信息,请参阅this post on security.stackexchange.comthis blog post on timing attacks

答案 1 :(得分:0)

比较哈希,您比较普通字符串的方式可能会使您的程序/应用/网站/易受timing attacks影响。
正常的字符串比较很快,你会尽快得到结果。但是当谈到安全性时,这种比较会泄漏信息。通过测量检查某些字符串所需的时间差异,攻击者可以确定他猜错了多少子字符串。 (Anthony Ferrara发布了一篇非常好的article详细解释了这一点)

为防止这种情况发生,我们必须使用完全相同的时间检查两个哈希值。在PHP(&gt; 5.6.0)中,您可以使用定时攻击安全字符串比较函数hash_equals()