提高已存储密码哈希的安全性

信息安全 密码 哈希 pbkdf2
2021-08-25 08:33:44

现在我们使用 1024 字节的 PBKDF2 和 256 字节的用户特定盐和变量迭代。但是,我更希望能够(也许每两年一次)能够完全增加算法中使用的轮次。BCrypt 或 PBKDF2 都不允许这样做,所以......

我应该忘记它,还是实现我们自己的使用 SHA512/256 的递归函数版本?这里的想法是获取密码,附加盐,散列,获取散列,附加盐,散列,获取那个散列,附加盐,散列......重复令人作呕。

...或者我们应该让系统在用户登录时每年用新的轮次重新哈希密码一次?

3个回答

构建自己的算法绝不是一个好主意。即使是训练有素的密码学家,即那些在学术界的黑暗隧道和科学大会的战场上辛勤工作多年的人,也只有在其他一切都失败时才会诉诸这种创造性。即便如此,他们也更愿意提出要由他们凶猛的同行验证的方案,当然不会立即部署到生产环境中。大多数学术培训是关于获得对自己领域危险的直观知识。

设计你的算法就像在雷区跳踢踏舞。

然而,从哈希值本身开始,简单地扩展存储哈希的迭代次数是不可能的,这常见候选者(PBKDF2、bcrypt 和 scrypt)的一个已知缺陷。如果你不得不忍受它,你可以尝试那里描述的方案,但我明确否认这样会增加安全性我在该领域的培训和多年经验让我可以自信地说,我建议的额外哈希轮次不会降低安全性。

未来情况会更好,因为新的密码哈希算法公开竞赛已经启动,使用之前的 AES、eSTREAM 和 SHA-3 竞赛的模型。提交截止日期为 2014 年 1 月。根据临时时间表,将在 2015 年年中获得“优秀算法”组合。征求意见稿明确包括以下所需功能:

能够在不知道密码的情况下将现有哈希转换为不同的成本设置。

因此,我们可以希望在两年多的时间内解决您的问题。仅仅两年,按照密码设计标准来说,这真的很快。

同时,您将不得不采用通常的等待用户登录的安排,以便他们的密码可以通过更多的迭代来重新散列。大多数超过一年未登录的用户可能无论如何都忘记了密码。

经典的解决方案是您在最后编写的解决方案——“在用户登录时重新哈希密码 [..]”。换句话说:

  1. 用户登录,并以纯文本形式显示他的密码。
  2. 系统使用旧哈希对密码进行哈希处理,并将其与存储的值进行比较。
  3. 如果它们匹配,则使用新的更强的散列算法对明文密码进行散列,并将结果写入数据库。
  4. 对于在特定时间内未登录的帐户,请向他们发送一封礼貌的电子邮件,要求他们重新访问该网站,否则他们的帐户将被删除。

也就是说,请注意不要过度使用密码哈希。密码散列的主要目的是在成功破解延迟攻击者利用密码的时间——让最终用户有时间更改他们的密码。在某一点上,与系统中的其他组件相比,密码散列变得“足够好”。

显然,首先防止攻击者破坏系统是最好的——所以要保持足够的精力来构建和维护安全系统。(如正在进行的代码安全审计、Web 应用程序防火墙规则集维护、入侵检测系统监控和配置、保护备份媒体等)

我有同样的要求,并以这种方式解决它:

  • 使用 PBKDF2 和当前为 16 的工作因子(即 2^16 次迭代)以通常的方式散列盐和密码。将盐、哈希、工作因子等作为一行存储在数据库表中。
  • 异步(即不影响最终用户)再执行 3 次,每次将工作因子增加 1。所以现在我有该用户的 4 个数据库行,工作因子分别为 16、17、18 和 19。
  • 我总是使用工作系数最低的行来验证密码,但每 2 年我会删除工作系数最低的行。