Github的securing webhooks page说:
不建议使用普通
==
运算符。像secure_compare
这样的方法执行“常量时间”字符串比较,这使得它不会受到针对常规相等运算符的某些定时攻击。
我在比较密码时使用bcrypt.compare('string', 'computed hash')
。
是什么让这成为一种安全的比较"我可以使用Node中的标准crypto
库吗?
答案 0 :(得分:24)
"恒定时间"字符串比较是,无论比较目标是什么(未知值),比较将花费完全相同的时间量。这个"恒定的时间"向攻击者显示没有关于未知目标值可能是什么的信息。通常的解决方案是,即使发现不匹配,也会比较所有字符,因此无论在哪里发现不匹配,比较都会在相同的时间内运行。
当某些条件为真时,其他形式的比较可能会在较短的时间内返回答案,从而允许攻击者了解他们可能缺少的内容。例如,在典型的字符串比较中,只要找到不相等的字符,比较就会返回false。如果第一个字符不匹配,那么比较将在比它更短的时间内返回。一个勤奋的攻击者可以利用这些信息进行更聪明的暴力攻击。
A"恒定时间"比较消除了这些额外的信息,因为无论两个字符串如何不相等,函数将在相同的时间内返回其值。
在查看nodejs v4 crypto library时,我没有看到任何函数的迹象进行常数时间比较,并且每this post,有一个关于nodejs加密库这一事实的讨论缺少此功能。
编辑:节点v6现在有crypto.timingSafeEqual(a, b)
。
此buffer-equal-constant-time module中还有一个恒定的时间比较功能。
答案 1 :(得分:5)
jfriend的答案一般是正确的,但就这个特定的上下文(比较bcrypt操作的输出与存储在数据库中的内容)而言,使用" ==没有风险"
请记住,bcrypt旨在成为单向函数,专门用于抵御攻击者获取数据库时的密码猜测攻击。如果我们假设攻击者拥有数据库,则攻击者不需要时间泄漏信息来知道他猜测密码的哪个字节是错误的:他可以通过简单地查看数据库来检查自己。如果我们假设攻击者没有数据库,那么计时泄漏信息可能会告诉我们在一个对攻击者来说理想的场景中他猜测哪个字节是错误的(根本不现实)。即使他能获得这些信息,bcrypt的单向属性也无法利用知识获取。
总结:一般来说,防止计时攻击是一个好主意,但在这种特定情况下,您不会因使用" =="而使自己处于危险之中。
编辑: bcrypt.compare()函数已经is programmed to resist timing attacks,即使不这样做也没有安全风险。
答案 2 :(得分:3)
想象一下要比较的长块材料。如果第一个块不匹配且比较函数返回正确,则表示您已将数据泄露给攻击者。他可以处理第一个数据块,直到例程需要更长时间才能返回,此时他将知道第一个块匹配。
比较更安全的定时攻击数据的两种方法是散列两组数据并比较散列,或者对所有数据进行异或,并将结果与0进行比较。如果==只扫描两个数据块并且当它发现差异时返回,它可能无意中发挥“更温暖/更冷”并引导对手直接进入他想要匹配的秘密文本。