全面披露:我是该论文的作者之一。
一个精确的密码检查系统会存储一个标准的加盐的、计算缓慢的密码哈希值。当密码(例如 password123)向身份验证服务注册时,会选择一个随机盐“sa”(这应该是 16 个或更多随机字节)并应用一个计算缓慢的哈希函数 H:H(sa,密码 123)。结果,称为 h,与盐 sa 一起存储在数据库中。如前所述,应该选择 H 慢(计算 10 秒或 100 毫秒)。正确配置的 argon2、scrypt 或 PBKDF2 是不错的选择。
当用户稍后尝试登录时,如果他们输入密码,则会重新计算哈希值并根据存储的值进行检查。在上面的示例中,如果用户发送密码 123,则重新计算(再次缓慢) H(sa,password123) 并检查结果 --- 它与先前计算的 h 匹配并且可以允许登录。提交的密码与之前注册的密码的任何偏差都会导致完全不同的哈希值,并且登录失败。
我们的想法很简单:如果第一次检查失败,系统可以对提交的密码额外应用少量“校正”函数,然后对结果应用哈希算法。例如,我们可能会修复一个大写锁定校正函数 F_caps,该函数将密码作为输入并输出更改所有字母的大小写的密码:F_caps(PASSWORD123) = password123 和 F_caps(pAsSwOrD123) = PaSsWoRd123。我们还可以修复首字母大写校正器:F_first(Password123) = password123 和 F_first(pASSWORD123) = PASSWORD123。请注意,这些很容易实现。
然后进行容错检查,将对先前注册的盐、哈希对 (sa,h) 和提交的密码 pw 应用以下逻辑
如果 H(sa,pw) = h 或 H(sa,F_caps(pw)) = h 或 H(sa,F_first(pw)) = h 则允许登录
例如,如果一个提交 PASSWORD123,则检查将针对 PASSWORD123、password123 和 PASSWORD123,第二个检查成功。
几点:
1)离线暴力攻击的功效与之前完全一样。为什么?因为我们只存储 sa,h。给定 sa,h 的攻击者只会通过尝试正确密码的暴力攻击来学习密码,在我们的示例中为 password123。这里没有安全性损失,因为我们没有改变 H 的计算方式。
2)远程猜测攻击的安全性变化可以忽略不计。我们通过论文中的广泛分析展示了这一点,但归根结底,在现实世界中,最好的策略是提交最有可能达到某个阈值的密码(例如,许多网站在 10 次尝试失败后锁定帐户)。由于错字更正而执行的额外检查可能会帮助攻击者更加幸运,但我们证明它基本上可以忽略不计。如果有人担心它,我们会提供进一步减少它的技术。
3) Typo-tolerance 会增加登录服务器的 CPU 使用率(当 H 是 scrypt 或 argon2 等内存硬散列时,可能还会增加内存负载)。这是因为 H 的计算调用速度特别慢。在实践中,这似乎并没有您预期的那么大(在我们上面的示例中为 3 倍),因为无论如何用户最终会在拒绝后重新提交,而您为每次尝试付出代价。
4) 我们不建议允许任意拼写错误。目前这甚至是不可能的,因为它需要重新计算 H 的次数令人望而却步(记住它很慢!),无论如何这都是不安全的。需要根据原则性分析仔细选择允许哪些错别字。我们相信上面提到的两个校正器,大写锁定和首字母大写,是安全部署的明智之举,除此之外它开始变得更加细微。
我们添加了一个提供更多信息的常见问题解答:
https ://www.cs.cornell.edu/~rahul/projects/pwtypos.html