问题在于用户可访问性和攻击者模型之间的平衡。
第一个解决方案
If not password correct for a certain number of time:
block the user
send a reset link to the user
用户:可能被阻止,并且他们不喜欢重置
攻击者:通过尝试对所有用户进行身份验证来阻止所有用户(特别是如果所有登录名都是公开可用的)
第二种解决方案
If not password correct:
sleep(amount_of_time)
问题是: 'amount_of_time' 的值是多少?
用户:等待每个错误的“amount_of_time”可能很烦人
攻击者:继续尝试,测试/秒数较低
第三个解决方案
If not password correct:
sleep(amount_of_time)
amount_of_time = amount_of_time * 2
用户:密码错误少,不那么烦人
攻击者:通过发送大量错误密码来阻止用户连接
第四种解决方案
If not password correct for a certain number of time:
submit a CAPTCHA
用户:需要解析验证码(不太复杂)
攻击者:需要解析验证码(必须很复杂)
很好的解决方案(并且被很多网站使用)但要小心我们的验证码。实施。无论如何,有一个技巧(请参阅下一个解决方案)。
第五种解决方案
If not password correct for a certain number of time:
block the IP
(eventually) send a reset link
用户:用户可能因为无法正确记住密码而被阻止。
攻击者:用不同的用户尝试相同的密码,因为阻止是基于用户的登录次数。
最终解决方案?
If several login attempts failed whatever is the user by an IP :
print a CAPTCHA for this IP
用户:用户不能被 IP 封锁,但必须记住其密码。
攻击者:难以进行有效的蛮力攻击。
重要说明
登录表单或登录提交链接是否被阻止?阻止登录表单是没有用的。
抵抗暴力破解首先是密码复杂性的问题,因此您需要严格的密码策略(尤其是在分布式暴力破解的情况下)。
我没有提到用盐对密码进行哈希处理的事实,你已经在这样做了吗?因为如果访问密码数据库比暴力破解更容易,攻击者会选择这种解决方案(“一条链的强度取决于它最薄弱的环节”)。