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