有些(特别是银行)密码系统要求您输入密码中的三个指定字母才能登录。这旨在防止键盘记录器,可能还包括未加密会话的网线嗅探重放攻击。
显然,使用普通的密码散列算法无法实现这样的方案,因为您需要知道整个密码才能计算出散列值。
这种系统通常在服务器端存储什么信息以使其工作?
它们是以纯文本形式存储密码,还是每个字母的单独哈希值,或者其他什么方式?
有些(特别是银行)密码系统要求您输入密码中的三个指定字母才能登录。这旨在防止键盘记录器,可能还包括未加密会话的网线嗅探重放攻击。
显然,使用普通的密码散列算法无法实现这样的方案,因为您需要知道整个密码才能计算出散列值。
这种系统通常在服务器端存储什么信息以使其工作?
它们是以纯文本形式存储密码,还是每个字母的单独哈希值,或者其他什么方式?
如您所述,常规密码哈希方案无法在仅使用密码子串进行身份验证时起作用。 可以有多种实现此类系统的方法:
以明文形式存储密码:
存储加密密码,解密以检查:
存储所有(或足够多)可能子字符串的哈希值:
使用 k-out-of-n阈值秘密共享:
最终,如果数据库被攻击者入侵,所有这些方案都容易受到暴力破解攻击的威胁。根本原因在于典型密码(甚至是特别强的密码)的三个字母子串中没有很多熵,因此不需要很多次尝试就可以破解。
哪种方案最好?很难说。如果必须选择其中一种方案,我可能会选择使用强对称加密(如AES)进行加密存储,并使用单独的服务器或HSM处理加密和验证。这样,至少攻击者入侵前端服务器后不能只是复制数据库并在离线状态下攻击它(尽管如果HSM未实施有效的速率限制,他们仍然可以对HSM进行暴力破解攻击)。
然而,我要说的是仅使用部分密码进行身份验证的整个想法是有严重缺陷的:除了在一些特别受限制的攻击场景(例如只能观察一个认证事件且不能不停地尝试直到获取相同挑战的窃听者)之外,它实际上并没有提供所应具备的安全保障效益,而且通过减少成功验证所需的信息量从根本上削弱了安全性。有更好的解决方案,例如TANs,可以解决部分密码身份验证所要解决的安全问题。