【问题标题】:What's the difference between a secure compare and a simple ==(=)安全比较和简单的 ==(=) 之间有什么区别
【发布时间】:2015-09-14 17:58:43
【问题描述】:

Github 的 securing webhooks page 说:

不建议使用普通的== 运算符。像secure_compare 这样的方法会执行“恒定时间”字符串比较,从而使其免受针对常规相等运算符的某些定时攻击。

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

是什么让它成为“安全比较”,我可以使用 Node 中的标准 crypto 库来做到这一点吗?

【问题讨论】:

  • 我回滚了添加 ruby​​ 标记的编辑,因为看起来 OP 没有使用 Ruby,链接页面使用 Ruby 作为示例,但正在讨论与语言无关的概念。
  • @WallyAltman 实际上,我特别询问是否有 Nodejs 方法可以在没有第三方模块的情况下执行安全比较。但你是对的,问题的精神与语言无关。

标签: node.js security cryptography


【解决方案1】:

“恒定时间”字符串比较的要点是,无论比较目标是什么(未知值),比较都将花费完全相同的时间。这个“恒定时间”不会向攻击者透露关于未知目标值可能是什么的信息。通常的解决方案是比较所有字符,即使在发现不匹配之后也是如此,因此无论在哪里发现不匹配,比较都会在相同的时间内运行。

当某些条件成立时,其他形式的比较可能会在更短的时间内返回答案,从而使攻击者能够了解他们可能遗漏的内容。例如,在典型的字符串比较中,一旦发现不相等的字符,比较就会返回 false。如果第一个字符不匹配,则比较将在比匹配时更短的时间内返回。勤奋的攻击者可以使用此信息进行更智能的暴力攻击。

“恒定时间”比较消除了这些额外信息,因为无论两个字符串如何不相等,函数都会在相同的时间内返回其值。

在查看nodejs v4 crypto library 时,我没有看到任何用于进行恒定时间比较的函数的迹象,并且根据this post,有一个关于 nodejs 加密库缺少此功能的讨论。

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

这个buffer-equal-constant-time module也有这样一个恒定时间比较功能。

【讨论】:

  • Node.js 在 v6.6.0 - nodejs.org/dist/latest-v6.x/docs/api/… 中添加了 crypto.timingSafeEqual 方法
  • @SaugatAcharya - 谢谢,我将其添加到我的答案中。
  • 比较字符串a和b的完整示例(字符串不能传递给timingSafeEqual):const isEqual = crypto.timingSafeEqual( Buffer.from(a), Buffer.from(b) );
  • 请注意:如果ab 的字节长度不同,timingSafeEqual() 将抛出异常。
  • @mamacdon - 是的,正如the doc for timingSafeEqual() 所说:"a and b must both be Buffers, TypedArrays, or DataViews, and they must have the same byte length."
【解决方案2】:

jfriend 的回答总体上是正确的,但就这个特定的上下文而言(将 bcrypt 操作的输出与存储在数据库中的内容进行比较),使用“==”没有风险。

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

总结:一般来说,防止定时攻击是一个好主意,但在这种特定情况下,使用“==”不会将自己置于任何危险之中。

编辑: bcrypt.compare( ) 函数已经is programmed to resist timing attacks,即使不这样做绝对没有安全风险。

【讨论】:

  • 如果 === 在这种情况下没有安全风险,你为什么说 GitHub 会提出这一点并粗体他们的建议? developer.github.com/webhooks/securing
  • @LukeWilliams 比较 HMAC 签名与比较 bcrypt 哈希输出是不同的上下文。作为一名安全专家,我通常建议您使用默认安全选项:程序员不是密码学专家,无法理解每个可能的用例的微妙之处。 OTOH 我是一名密码学家,我的观点是在 bcrypt 哈希比较的背景下,不太安全的选项是不可利用的,并且该评论针对的是寻求更深入理解的真正聪明的人。
【解决方案3】:

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

比较数据更安全的两种方法可以避免定时攻击:对两组数据进行哈希处理并比较哈希值,或者对所有数据进行异或并将结果与​​ 0 进行比较。如果 == 只扫描两个数据块并在发现差异时返回,它可以无意中播放“温暖/寒冷”并引导对手直接进入他想要匹配的秘密文本。

【讨论】:

    猜你喜欢
    • 2011-01-23
    • 2019-05-21
    • 1970-01-01
    • 2012-08-26
    • 1970-01-01
    • 2012-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多