我已经看到了一些关于这方面的帖子,但我还没有看到确切的答案。因此,我想我会尝试在一个新的背景下(国防部(重申这个问题。
根据DISA的">应用程序安全和开发STIG,V3R2",第3.1.24.2节密码复杂性和维护,国防部企业软件对密码有一个相当严格的指导方针:
-
密码长度必须至少为15个字符。
-
密码必须包含大写字母、小写字母、数字和特殊字符。
-
更改密码时,用户不得能够使用诸如姓名、电话号码等的个人信息,账户名称或字典单词。
-
密码必须在60之后过期天。
-
用户不得重复使用以前的10个密码。
-
确保应用程序能够在更改密码时要求新帐户密码与以前的密码至少相差四个字符。
-
用户更改密码的次数不得超过每天一次,管理员或特权人员除外使用者特权用户可能需要重置用户的遗忘密码以及每天多次更改密码的能力。
正如NullUserException的帖子中所述,为了让开发人员能够真正检查最后X个密码数量(并确保新密码与以前的密码不同[bullet 6](,密码必须使用可逆方法加密,而不是散列密码(这更不安全,即使我使用的是美国国家安全局批准的加密算法(。提议的答案似乎很有道理,尽管似乎存在一些差异和争论,正如Dan Vinton的帖子所示。
我想这里真正的问题是,是否有人能够在不降低系统安全性的情况下实现所有这些看似常见的密码复杂性约束?
编辑:漏洞APP3320.7(要点6(指出:"确保应用程序能够在更改密码时要求新帐户密码与以前的密码至少相差四个字符。"这让我相信,我必须运行Levenstein等字符串相似性算法来检查相似性。我不能在杂碎/盐上做这件事。如果我错了,请告诉我?
所述的字符距离要求仅适用于前一个密码,而不是前10个密码。假设你的密码工具需要输入当前密码和新密码,你只需对照它进行检查;不需要在那里存放任何东西。(在你提到的帖子的答案上也注明了这一点。(
当然,不匹配前10个密码中任何一个的要求,只需对照旧的哈希进行检查即可。
使用可逆方法生成密码派生密钥不是一种安全的做法,您不能这样做。您也不能存储纯文本身份验证信息。由于你将存储密钥(如果你有这种恋物癖,可能还会存储盐(,所以保存最后10个密钥的副本并对照它们检查新提交的密码是微不足道的。
要求新密码与以前的N个密码相差M个字符是疯狂的,因为这意味着密码历史记录要么是明文的,要么是可逆加密的,两者都不安全。
在存储空间成本高昂的情况下,将密码历史记录限制为"最后N次",从而将密码更改频率限制为"每天一次"是有意义的,但在存储非常便宜的今天,这是没有意义的。一个更合理的政策是"新密码不得与任何已知的旧密码相同",并保持不变。放弃"最后一个N",放弃"每天最多一次"规则,这只是为了防止用户绕过历史记录。
一些密码管理系统支持这种配置(并且多年来一直支持这种配置(。示例:https://hitachi-id.com/password-manager/features/password-policy-enforcement.html