像PBKDF2这样的关键拉伸函数允许您通过调整迭代计数(或其他函数的其他等效参数)来控制散列密码所需的时间。您正确地观察到在使密码难以通过暴力破解和避免 DoS 攻击之间存在权衡。您需要选择一个迭代计数来平衡这两个考虑因素。
请记住,现代 CPU 每秒可以计算数百万次哈希迭代。即使您使用仅 1000 次的迭代计数,这仍然使破解密码比不迭代哈希要困难 1000 倍,即使使用 1000 次迭代对单个密码进行哈希处理只需要大约一毫秒。
还有其他方法可以避免或减轻登录 DoS 攻击。例如,您可以实施基于 IP 的限制,这样每个 IP 地址每分钟只能进行一些有限的登录尝试次数。当然,分布式 DoS 攻击可以解决这个问题,但这仍然是任何潜在攻击者都需要克服的障碍。
此外,如果您实施登录反 CSRF 令牌(并且您应该这样做),它们还将通过在进行任何登录尝试之前需要额外的往返来获取令牌来保护您免受某些简单类型的登录 DDoS 攻击。 CAPTCHA可能是另一种处理登录 DoS 尝试的有用方法。最后,您可能希望将所有登录请求限制到一组单独的服务器和/或进程,并具有适当的资源限制,这样即使对登录表单的成功 DoS 攻击也不会破坏您网站的其余部分。
如果你真的想变得花哨,你甚至可以要求客户提交一份加密工作证明,或多或少等同于对密码进行哈希处理。例如,您可以向客户端发送一个随机字符串,并要求它向该字符串发回一个后缀,以便随机字符串加上后缀散列到一个以n零位结尾的值,其中 2 n大约是您的迭代计数。存在可用于实现此类系统客户端的JavaScript 加密库。