密码扩展 – 一种缓解CPU泛滥的方法

我现在正在所有网站上使用密码拉伸来获取所有用户帐户密码。 在db中,我存储了一个迭代计数和随机分配的盐以及最终的哈希值。 我使用SHA512作为哈希算法。 我在.Net 3.5 4.0(双框架库)中使用C#。

对于只获得随机分配密码的帐户(例如Web服务API用户等),我将迭代计数保持在一个范围内,使得密码检查不超过1秒左右。 多年来,根据这些网站是否坚持(!),我将考虑增加这些范围与CPU功率一致。

对于用户可能自己选择密码的帐户,我已经加快了迭代次数,因此在执行迭代时登录可能需要大约5秒。

所以我对密码的安全性感到满意; 但是现在我还有另外一个问题 – 如果我让8个不同的人立刻登录,我可以使用100%的使用率8个核心cpu充满5秒钟!

我目前的解决方案是使用迭代阈值:如果拉伸操作超过此值,我将其推送到由单个线程处理的队列。 我可以进一步扩展它,以便它最多使用机器中的一半处理器。

我还能做些什么吗? 您是否为密码存储和登录实现了此模式 – 您做了什么?

密码拉伸的想法是让攻击者做繁重的工作:

当客户端想要登录时,服务器会提出挑战。 客户端执行资源密集型计算并向服务器发送响应。 服务器应该能够用很少的资源确定响应是否有效。

因为客户端正在做繁重的工作而客户端需要为每次登录尝试提出新的挑战,所以对于攻击者来说,强制所有可能的密码组合(希望)过于昂贵。

看看Salted Challenge Response Authentication Mechanism(SCRAM) 。

密码拉伸的最大好处是,计算是在客户端进行的,因此它们不应该影响您的服务器,同时仍然提供良好的保护?
坦率地说,如果你在你的服务器上实现它,你做错了,错过了重点:-)

您确定黑客不会更容易在干净的文本中截取密码,然后破解数据库信息。 我将简化算法来创建和检查密码,并将更多地关注重要的安全性。

像Jon说:

我觉得你有点过头了…… 🙂

我认为不止一次应用SHA512没有任何额外的价值。

您是否拥有以下身份validation工作流程:

  1. 用户在Web表单上输入用户名和密码,并以纯文本或SSL方式将其发送给服务器;
  2. 服务器计算适当的哈希/盐渍哈希/以及与数据库中存储的哈希/盐水哈希/哈希/哈希值相比
  3. 服务器将计算的哈希与存储在数据库中的哈希进行比较。

如果是这样,那么散列没有多大意义,因为潜在的攻击者无论如何都无法发送直接散列。 在这种情况下,不进行散列会使您的系统更安全,而是在服务器响应请求之前延迟 – 这可以通过便宜得多的Thread.Sleep(1000)技术来实现……