使用按位运算符testingSHA-256摘要的相等性

我正在nodeJS应用程序中实现一个令牌系统,我需要检查两个使用SHA256散列的string是否相等。 我最初的想法是,我可以简单地使用严格的相等运算符( hash1 === hash2 )来testing相等性,因为摘要如果具有相同的input应该产生相同的string。 不过,我已经看到了Paragon Initiative的一篇文章,声称比较每个字符的ascii代码中使用按位运算符的string更安全。

要比较摘要令牌,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; } 

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

这比使用严格的string比较更有效吗? 哈希摘要只是string,我不知道为什么一个简单的string比较会比明确检查string中的每个单字节有效。

文章编号: https : //paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence Code Ref: https : //github.com/psecio/gatekeeper/blob/7b8ec374e208148692316a34c1b4700d5407ef9b/src /Psecio/Gatekeeper/Gatekeeper.php

更新:

我研究了它,npm上的scmp工具可以用于Javascript中的常量string比较。

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

编辑: 在PHP中使用内置的hash_equals进行计时攻击比较。 请参阅hash_equals PHP文档。 下面的解释。

你不应该使用string比较来testing散列,因为它们被优化,只要他们能够告诉string不相等就返回。

在正常的代码中,这是一件好事。 你想尽快得到结果。 当涉及到安全,但泄漏的信息。

如果攻击者重复提交不同的string,并能够测量时间的差异,直到他被拒绝访问,他可以使用这种方法来确定他已经正确猜测了多lessstring。

有关更多信息,请参阅security.stackexchange.com上的 此文章以及有关计时攻击的博客文章 。

比较哈希比较正常string的方式可以使您的程序/应用程序/网站/任何易受时间攻击的东西 。
普通的string比较很快,你会尽快得到结果。 但是就安全性而言,这种比较会泄漏信息。 通过测量检查某些string所需的时间差异,攻击者可以确定他已经正确猜测了多less个子string。 (安东尼·费拉拉发表了一篇很好的文章 ,详细解释了这一点)

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