BCRYPT(SHA1(密码))的安全性如何

信息安全 密码 哈希 bcrypt
2021-08-18 14:48:26

这个问题是前一个问题的一个分支: 将盐存储在与哈希密码相同的字段中是否安全/明智?

假设您运行一个 Web 门户,并将密码存储在 SHA1 哈希中。您如何将其升级为 BCRYPT 哈希?

通常,您会等待用户登录,然后将他们的密码(从他们输入的明文)重新散列到 BCRYPT。但是所有用户都可能需要一段时间才能登录到您的平台,并且总会有不活跃的用户永远不会回来。

另一个建议(我第一次从 Troy Hunt 那里听到)是对数据库中现有的 SHA1 密码进行 BCRYPT。实际上你会BCRYPT(SHA1(plaintext_password))这样,系统上的所有用户都会立即升级到 BCRYPT,无论他们的活动如何。

这样,对您的数据库的破坏不会暴露尚未登录但仍在 SHA1 上的用户。

问题是:

  1. IsBCRYPT(SHA1(plaintext_password))在安全性上等同于BCRYPT(plaintext_password)
  2. 如果不是——为什么?差距是否足够合理,可以考虑这个选项?

该问题侧重于 BCRYPT(SHA1),但可以轻松应用于任何两种哈希算法,最后应用更强的哈希算法。

2个回答

首先,感谢您花时间确定如何正确执行此操作并提高用户的安全性!

在考虑遗留散列的同时迁移密码存储是相对常见的

对于您的迁移方案,bcrypt(base64(sha1(password)))将是一个合理的平衡它避免了 null 问题重要 - 您绝对不想忽略 base64 阶段!),回避 bcrypt 的原生 72 个字符限制,并且与您现有的哈希 100% 兼容。

在基本情况下,您只需使用 散列所有现有 SHA1 bcrypt(base64(sha1)),然后使用完整序列散列所有新密码。(您也可以改用 SHA256,尽管这会稍微增加您的代码复杂性,以检查是否使用了 SHA1 或 SHA25(或者只尝试它们,如果其中一个成功则通过)从长远来看,SHA256 将更能抵抗冲突,所以会是更好的选择)。

为了抵抗暴力破解,这不仅等同于 bcrypt,而且在理论上更胜一筹(尽管在实践中,72 个字符对于密码存储来说是如此之大,而不是它们实际上是相同的)。

奖金建议:

  • 确保使用足够高的 bcrypt 工作因子以抵抗离线攻击 - 您的用户可以容忍的最高值,100 毫秒或更高(可能至少工作因子为 10)。对于 1 秒以下的速度,对于攻击者而言,bcrypt 实际上可能比其现代替代品 scrypt 和 Argon2 (YMMV) 慢(对防御者更好)。
  • 将工作因子的默认值存储为系统范围的可配置变量,以便您可以随着底层硬件速度变得更快(或更分散)而定期增加它。

更新:请注意,一般来说,将快速散列包装在慢速散列中是一种反模式(应保留用于迁移或临时目的)。有关更多信息,请参阅我的答案简而言之,即使尚未破解自己,也可以在慢哈希内破解,然后直接破解更快对于针对高价值用户和更大的目标哈希集的针对性攻击都是如此。这种攻击称为“哈希去壳”,高级密码破解研究人员众所周知。绝对是不直观的,因此请参阅我的其他答案以进行扩展讨论,而不是尝试在这里讨论。

这会将密钥空间限制为大约 2 160,因为 SHA-1 输出 20 字节摘要,但其他方面都很好。事实上,bcrypt 的输入限制为 72 字节,因此人们首先使用快速、加密安全的散列来散列密码并不少见。由于限制大于 SHA-1 的摘要大小,因此您可能希望使用具有更大摘要的散列。请注意,null 问题需要将摘要转换为另一种编码,例如 base64。

如果您已经拥有一个充满 SHA-1 哈希值的数据库,那么通过 bcrypt 运行它们是完全可以的。