【发布时间】:2017-04-05 23:37:34
【问题描述】:
我正在一个 nodeJS 应用程序中实现一个令牌系统,我需要检查两个使用 SHA256 散列的字符串是否相等。我最初的想法是,我可以使用严格的相等运算符 (hash1 === hash2) 简单地测试相等性,因为如果摘要具有相同的输入,它们应该产生相同的字符串。但是,我看到 Paragon Initiative 的一篇文章声称在每个字符的 ascii 代码上使用按位运算符比较字符串更安全。
为了比较摘要标记,Paragon 代码使用以下代码 sn-p (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。
这比使用严格的字符串比较更有效吗?哈希摘要只是字符串,我不知道为什么简单的字符串比较不如显式检查字符串中的每个 sing 字节有效。
文章参考: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 日,根据 nsp 和 snyk 工具,它没有漏洞。
【问题讨论】: