出于明显的安全原因,不应以纯文本形式存储密码:您必须存储散列,并且还应谨慎生成散列,以避免彩虹表攻击。
但是,通常您需要存储最后的n个密码,并在不同密码之间进行最小的复杂度和最小的更改(以防止用户使用诸如Password_1,Password_2,...,Password_ n之类的序列)。使用纯文本密码将是微不足道的,但是如何仅存储散列呢?
换句话说:如何实现安全的密码历史记录机制?
出于明显的安全原因,不应以纯文本形式存储密码:您必须存储散列,并且还应谨慎生成散列,以避免彩虹表攻击。
但是,通常您需要存储最后的n个密码,并在不同密码之间进行最小的复杂度和最小的更改(以防止用户使用诸如Password_1,Password_2,...,Password_ n之类的序列)。使用纯文本密码将是微不足道的,但是如何仅存储散列呢?
换句话说:如何实现安全的密码历史记录机制?
Answers:
存储散列并针对存储的散列验证输入的密码,这与登录时验证密码的方式相同。您将必须根据数字模式从给定的密码中生成“替代”密码,以检测“最小”变化。
登录时,您已经针对哈希验证了输入的密码,无需以明文形式存储密码。更改密码时,可以使用相同的技巧,只需对照历史哈希值检查输入的“最小更改”生成的密码即可。如果新密码令人满意,则将当前密码哈希移至历史记录集,并用新密码的新哈希替换。
用户更改密码时,要求他们输入以前的密码。现在您可以访问两个纯文本密码,即使您没有在数据库中存储纯文本密码也是如此。
对这两个密码执行所需的任何验证。这不会阻止用户在两个密码之间进行替换(带有后缀-您可以根据其他答案中的建议防止直接更改密码),但是可以避免更为公然的情况。
potatoSalad1
,并且想要更新为potatoSalad2
,则您会说更改太小,因为此时您同时拥有两个纯文本密码。但是比这更远,您只有哈希,并且哈希的性质是您无法确定两个哈希是否具有相似或完全不同的纯文本作为输入。
要添加到@martijnPieter的答案中,可以通过基于新密码和旧密码(您都可以使用)进行短暂的暴力破解来实现最小的更改
例如,您可以遍历所有密码与新密码之间的汉明距离为1或2的所有密码,并查看其是否与旧密码匹配
但您可能要注意,这会降低用户对密码进行哈希处理的信心(因为您实际上是在说可以找回以前的密码来拒绝新密码)
这实际上是@Brian聪明答案的补充。还可以@Martijn Pieters添加有关如何基于当前密码强行破解旧密码的详细信息,以及@ratchet怪胎的“汉明距离”。我不会删除我的答案,因为我认为它提供了支持他们的有趣背景。
最先进的密码存储需要为每个用户使用多轮强大的单向加密哈希(SHA-512 +),并带有唯一的盐(128位+)。但是不要试图存储有关每个密码的其他信息。您将存储的有关每个密码的信息越多,破坏哈希算法的安全性就越多。
考虑一下知道暴力破解密码变得多么容易:
美国键盘具有95个可打印字符,因此知道密码的长度为7个字符可产生95 ^ 7 = 69,833,729,610,000 = 7x10 ^ 13排列。如果确实是随机的,则可能需要一年时间才能在单个3Ghz处理器上破解它。但:
因此(由于@Hellion而已更正):
26^4 (charcters 2-5 are known upper or lower-case)
x 100 (characters 1 & 7 are digits)
x 32 (character 6 is a symbol)
====
1,462,323,200 possible passwords.
那更容易破解50,000次!在这种情况下,存储良好的信息以防止使用相似的密码,使您可以花7年的时间来破解7个字符的密码,从一年下来到几个小时。现在,在功能强大,具有良好视频卡和耐心的多处理器桌面上对所有密码进行解码非常可行。我希望这个简单的示例能够说明,您越能有意义地比较相似的密码,则哈希处理的安全性就越差。
带有密码的数据库会定期被盗,每个月的新闻中都会有大量闯入事件。哎呀,就在上个月,SC州失去了每个人的社会保险号码 -哎呀!这些违规行为又掩盖了多少?
对我来说,最可怕的事情是,当人们为多个站点选择相同或相似的密码时,如果将其分成一个站点,攻击者便可以访问所有站点。我希望看到一种行之有效的防止这种情况的方法,尽管我认为防止最常见的错误密码将比阻止单个用户在同一站点内重用其错误密码有所帮助。我最好建议的是公司范围内的政策,即使用安全的密码管理器,该管理器为每个用户生成高度随机的密码并安全地存储它们。
首先,您可以存储最后一个“ n”个先前密码的哈希,因此您可以检查其新密码是否与先前密码重复。您还拥有他们当前密码的纯文本(因为他们已经登录或提供给您以验证他们的密码更改请求)和他们的新密码,因此您可以检查这两个密码之间的最小更改。
如果(对您而言)将这两个密码与之前的“ n”个密码直接进行比较非常重要,那么您必须存储(加密)这些密码以便以后可以检索它们。
虽然这样做可能被视为安全缺陷,但可以实施加密方法以提供足够的安全性。
然后,无论何时更改密码,您都可以取消对所有旧密码的加密,并进行所有最小更改测试。
现在,如果某人拥有此人的密码,并且知道所有其他必要的详细信息,则可以为该人取消对该信息的加密。但是,如果他们已经有了该人的密码,他们就可以以该人的身份登录并访问该人的帐户。
同样,对于旧密码,可能不必严格以纯文本形式存储它们。它们可以以某种混淆的方式存储。或存储为密码中字母的字母顺序列表。
我并不是说在一般情况下建议这样做,但是假设您所描述的任务在您的情况下是必需的,那么这是通过一些安全措施来完成此任务的一种方法。