出于明显的安全原因,密码不应以纯文本形式存储:您必须存储哈希,并且还应仔细生成哈希以避免彩虹表攻击。
但是,通常您需要存储最后 n 个密码,并在不同密码之间强制实施最小的复杂性和最小更改(以防止用户使用 Password_1、Password_2、...、Password_n) 等序列。这对于纯文本密码来说是微不足道的,但是如何通过仅存储哈希来做到这一点呢?
换句话说:如何实现安全的密码历史记录机制?
存储哈希并根据这些存储的哈希验证输入的密码,就像登录时验证密码一样。您必须根据数字模式从给定的密码中生成“替代”密码,以检测您的“最小”更改。
登录时,您已经根据哈希验证输入的密码,无需以明文形式存储密码。在更改密码时,同样的技巧也有效,只需根据历史哈希检查输入和“最小更改”生成的密码即可。如果新密码令人满意,请将当前密码哈希移动到历史集,并将其替换为新密码的新哈希。
当用户更改其密码时,要求他们输入以前的密码。您现在可以访问两个纯文本密码,即使您没有在数据库中存储纯文本密码也是如此。
对这两个密码执行您想要的任何验证。这不会阻止用户在两个密码之间交替(带有后缀 - 您可以根据其他答案中的建议防止直接交替),但它会防止更明显的情况。
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.
破解起来要容易5万倍!在这种情况下,存储良好的信息以防止类似的密码,已经将7个字符的密码的破解时间从一年缩短到几个小时。在功能强大的多处理器台式机上使用良好的视频卡和一点耐心解码所有密码现在非常可行。我希望这个简单的例子表明,您比较类似密码越有意义,您的哈希就越不安全。
带有密码的数据库经常被盗,每个月都有巨大的闯入新闻。哎呀,就在上个月,南卡罗来纳州失去了每个人的社会安全号码——哎呀!这些违规行为还有多少被掩盖?
对我来说最可怕的事情是当人们为多个站点选择相同或相似的密码时,因此闯入一个站点可以让攻击者访问所有站点。我很想看到一种行之有效的方法来防止这种情况,尽管我认为防止最常见的错误密码比防止单个用户在同一站点中重复使用他们的错误密码更有帮助。我能建议的最好的是公司范围内的策略,使用安全的密码管理器,为每个用户生成高度随机的密码并安全地存储它们。
首先,您可以存储最后“n”个先前密码的哈希值,以便检查其新密码是否与以前的密码重复。您还拥有其当前密码的纯文本(因为他们已登录或向您提供密码以验证其密码更改请求)及其新密码,因此您可以检查这两个密码之间的最小更改。
如果(对您来说)直接将这两个密码与“n”以前的密码进行比较非常重要,那么您必须存储这些密码(加密)以便以后能够检索它们。
虽然这样做可能被视为安全漏洞,但可以实施加密方法来提供足够的安全性。
然后,无论何时更改密码,您都可以取消加密所有旧密码,并进行所有最小更改测试。
现在,如果有人拥有此人的密码,并且知道所有其他必要的详细信息,他们可以为这个人解密此信息。但是,如果他们已经拥有此人的密码,则他们已经可以以此人的身份登录并访问此人的帐户。
此外,对于旧密码,它们可能不必以严格的纯文本形式存储。它们可以以某种混淆的方式存储。或存储为按字母顺序排列的密码字符列表。
我并不是说在一般情况下这是建议做的事情,但是假设您描述的任务在您的情况下是必需的,那么这是通过一些安全措施完成它的一种方法。