安全比较和简单==(=)之间的区别是什么

Github的安全webhooks页面说:

不build议使用普通的==运算符。 像secure_compare这样的方法执行“恒定时间”的string比较,这使得它可以安全地抵御常规等式运算符的某些定时攻击。

比较密码时bcrypt.compare('string', 'computed hash')我使用bcrypt.compare('string', 'computed hash')

是什么让这个“安全的比较”,我可以使用Node中的标准crypto库吗?

“恒定时间”string比较的要点在于,无论比较对象是什么(未知值),比较都将采用完全相同的时间量。 这个“恒定的时间”没有向攻击者揭示未知的目标值可能是什么信息。 通常的解决scheme是,即使在发现不匹配的情况下,也会比较所有字符,因此无论发现何处不匹配,比较都会在相同的时间内运行。

其他forms的比较可能会在某些条件成立的情况下以较短的时间返回答案,这使得攻击者可以了解他们可能会丢失什么。 例如,在典型的string比较中,只要发现不相等的字符,比较就会返回false。 如果第一个字符不匹配,那么比较的时间就会比返回的时间短。 勤奋的攻击者可以利用这些信息进行更聪明的暴力攻击。

“恒定时间”比较消除了这个额外的信息,因为不pipe两个string如何不相等,函数都会在相同的时间内返回它的值。

在查看nodejs v4encryption库时 ,我没有看到任何函数的迹象做恒定时间比较,并且在这篇文章中 ,讨论了nodejsencryption库缺less这个function的事实。

编辑:节点v6现在有crypto.timingSafeEqual(a, b)

这个缓冲区等时恒定时间模块中还有一个恒定的时间比较function。

jfriend的答案在一般情况下是正确的,但就这个特定的上下文而言(比较bcrypt操作的输出与存储在数据库中的输出),使用“==”没有风险。

请记住,bcrypt被devise成一个单向函数 ,当攻击者掌握数据库时专门用来抵御口令猜测攻击。 如果我们假设攻击者拥有数据库,那么攻击者就不需要定时泄漏信息来知道他猜测密码的哪个字节是错误的:他可以通过简单地查看数据库来检查自己。 如果我们假设攻击者没有数据库,那么定时泄漏信息可能会告诉我们在对于攻击者来说理想的情况下(他们根本不现实)他猜测哪个字节是错误的。 即使他可以得到这些信息,bcrypt的单向性也阻止了他利用知识获取。

总结:防止计时攻击一般来说是个好主意,但在这个特定的背景下,你并没有使用“==”使自己处于危险之中。

编辑: bcrypt.compare()函数已经被编程来抵抗定时攻击,即使没有这样做绝对没有安全风险。

想象一下比较长的材料块。 如果第一个块不匹配,并且比较函数返回正确,那么你已经泄露了数据给攻击者。 他可以处理第一个数据块,直到例程需要更长时间才能返回,此时他将知道第一个数据块匹配。

比较定时攻击更安全的数据的两种方法是对两组数据进行散列,并比较散列,或对所有数据进行异或运算,并将结果与​​0进行比较。如果==只是扫描两个数据块并返回if当它发现一个不一致的时候,它可能会不经意地扮演“更冷/更冷”的angular色,引导对手在他想要匹配的秘密文本上。