假设我正在正确地进行密码散列并使用 bcrypt、scrypt 或 PBKDF2,我应该如何选择合适的难度系数?即 bcrypt 的轮次,PBKDF2 的迭代和 scrypt 的 maxtime,maxmem 或 maxmemfrac。
还要假设最坏的情况会发生,并且我的用户的哈希和盐(以及任何应用程序的盐或胡椒。你知道......最坏的情况。)将意外或故意泄露。
我需要选择一个值:
- 对我来说很容易。
- 对于攻击者来说太难了。
第一部分相对容易。如果我选择足够多的轮次使 bcrypt 花费 0.5 秒,我可以确定我的用户在登录时不会看到明显的减速。(无论如何,在 Web 应用程序中,0.5 秒并不是很长的时间。)我还知道通过测试该函数的循环,我每分钟可以处理比我目前看到的更多的登录。如果我获得的登录率增加,我可以减少轮数并在每个用户登录时迁移用户,或者我可以等待更好、更便宜的硬件。当我在升级周期中自然变得更好、更便宜的硬件时,我可以增加轮数来弥补。
更难回答的问题是对攻击者来说有多难。当然,这取决于特定攻击者的密码值,但对于这个问题,除了这些用户/密码组合中的大多数将在其他实际有价值的站点上工作这一事实之外,假设没有任何特殊价值。
如果我将 bcrypt 轮数更改为现在需要 0.01 秒而不是 0.5 秒,这是否改变了攻击者的等式,因此现在暴力破解密码的价值超过了暴力破解它的成本?我怎么知道它有没有?
基于了解以下内容,这似乎很容易计算:
- 一个通用的用户名/密码对值多少钱。
- 用 $difficulty_factor 暴力破解 $hash_function 的散列需要多少成本。
由于 scrypt 被设计为内存硬而不是 CPU 硬,因此 2. 的答案会因算法而异。随着 CPU/GPU 速度增加或 RAM 价格下降,这不是线性加速。
有没有一个地方可以找到随着新硬件可用而更新的上述信息?
到目前为止,我找到的关于密码价值的最佳资源是 Brian Krebs 的博客文章,例如this one和this one。对于每秒破解的哈希,这是DEFCON 的“如果可以的话,请破解我”竞赛。每美元破解的哈希值会很好。
请在您的答案中忽略这些算法中的任何算法缺陷。如果找到其中一个,我会简单地切换到其他替代算法之一。我认为,如果在其中任何一个中发现缺陷,它将遍布安全新闻。
刚刚在 Crypto.SE上从定义 scrypt的论文中找到了这张表:
我只需要每年更新该表即可。