Github的securing webhooks page说:
不建议使用普通的==
运算符。像secure_compare
这样的方法执行“常数时间”字符串比较,这使得它可以安全地免受针对常规相等运算符的某些定时攻击。
比较密码时使用bcrypt.compare('string', 'computed hash')
。
是什么让这成为一个“安全比较”,我可以使用Node中的标准crypto
库来完成这一点吗?
Github的securing webhooks page说:
不建议使用普通的==
运算符。像secure_compare
这样的方法执行“常数时间”字符串比较,这使得它可以安全地免受针对常规相等运算符的某些定时攻击。
比较密码时使用bcrypt.compare('string', 'computed hash')
。
是什么让这成为一个“安全比较”,我可以使用Node中的标准crypto
库来完成这一点吗?
4条答案
按热度按时间watbbzwu1#
“恒定时间”字符串比较的要点是,无论比较目标是什么(未知值),比较都将花费完全相同的时间。这个“恒定时间”不会向攻击者透露任何关于未知目标值可能是什么的信息。通常的解决方案是比较所有字符,即使在发现不匹配之后也是如此,因此无论在哪里发现不匹配,比较都在相同的时间内运行。
当某些条件为真时,其他形式的比较可能会在更短的时间内返回答案,这使得攻击者能够了解他们可能错过了什么。例如,在一个典型的字符串比较中,一旦发现不相等的字符,比较就会返回false。如果第一个字符不匹配,则比较返回的时间将比匹配时短。一个勤奋的攻击者可以使用这些信息来进行更聪明的暴力攻击。
“常数时间”比较消除了这些额外的信息,因为无论两个字符串如何不相等,函数都会在相同的时间内返回其值。
在查看nodejs v4 crypto library时,我没有看到任何进行常量时间比较的函数的迹象,并且根据this post,有一个关于nodejs crypto库缺少此功能的讨论。
编辑:Node v6现在有
crypto.timingSafeEqual(a, b)
。在这个buffer-equal-constant-time module中也有这样一个恒定时间比较功能。
dy1byipe2#
jfriend的回答大体上是正确的,但就这个特定的上下文而言(将bcrypt操作的输出与数据库中存储的内容进行比较),使用“=="没有风险。
记住,bcrypt被设计成一个单向函数,专门用于在攻击者获得数据库时抵抗密码猜测攻击。如果我们假设攻击者拥有数据库,那么攻击者不需要时间泄漏信息来知道他对密码的猜测是错误的:他可以通过查看数据库来检查自己。如果我们假设攻击者没有数据库,那么时间泄漏信息可能会告诉我们,在攻击者理想的情况下(根本不现实),他的猜测中哪个字节是错误的。即使他可以获得这些信息,bcrypt的单向属性也会阻止他利用这些知识。
总结:一般来说,防止时间攻击是一个好主意,但在这个特定的上下文中,使用“=="并不会让自己处于任何危险之中。
**编辑:**bcrypt.compare()函数已经被编程为抵抗定时攻击,即使不这样做绝对没有安全风险。
kmbjn2e33#
想象一个很长的材料块进行比较。如果第一个块不匹配,并且比较函数立即返回,那么您已经将数据泄露给了攻击者。他可以处理第一个数据块,直到例程需要更长的时间才能返回,此时他将知道第一个块匹配。
比较数据的两种方法是对两组数据进行散列并比较散列,或者对所有数据进行XOR并将结果与0进行比较。如果==只是扫描两个数据块,并在发现差异时返回,它可能会无意中播放“更热/更冷”,并引导对手直接找到他想要匹配的秘密文本。
zvokhttg4#
不同之处在于,secret和测试字符串之间的安全比较在运行时不会泄露有关secret的信息。例如,假设秘密是
aaaaaaaaab
,你与测试字符串b
,bbbbbbbbbb
和aaaaaaaaaa
进行比较。一个经典的比较会立即产生false,因为b
的长度不匹配。Forbbbbbbbbbb
几乎立即为false,因为第一个字符不匹配。Foraaaaaaaaaa
也为false,但不是立即为false(需要更多的微秒或纳秒)。所以,时间越长,你的测试字符串就越接近秘密。例如,攻击者可以尝试通过发送许多不同长度的测试并找到最小的测试来猜测长度。然后,他可以继续以类似的方式找到第一个字符,依此类推,直到找到秘密。为了避免这种情况,正如@WDS所建议的那样,你可以做一个简单的for循环:
被接受的答案指向Node的
timingSafeEqual(a, b)
,它主要是为哈希输入设计的,因为正如评论中所说,它期望输入具有相同的长度。使用这个函数而不使用哈希可能会给你带来麻烦,因为当输入长度不匹配时,你不能只返回false
,因为这会泄露关于秘密长度的信息。