【问题标题】:Salted hashes and password histories加盐哈希和密码历史
【发布时间】:2010-11-30 15:49:30
【问题描述】:

想知道每次更改密码时盐对于单个给定用户是否唯一是否重要,或者每次重复使用相同的盐是否不是什么大问题。

我目前每次给定用户更新密码时都会生成一个新的随机字符串作为盐。这样,每次用户有一个新密码时,他们也是一个盐变化。这很容易做到,何乐而不为。

嗯...这就是为什么。我需要存储以前的 X 密码以确保密码不会被重复使用。在过去(我最后一次为此编写代码时),我可以只存储以前的 MD5 哈希值,并将新的哈希值与该列表进行比较。好吧,现在我使用的是加盐哈希,每次加盐都是唯一的,这些比较不再可能,因为不再知道以前的盐。

为了使该系统正常工作,我有两个选择:除了最终的哈希值之外,还存储盐的历史记录,或者在每次密码更新时为任何给定用户重复使用相同的盐。这些中的任何一个都可以让我建立可以与历史相比的价值观。

后者工作量少,但它是否失去任何力量?从实际的角度来看,我不认为它确实如此。以为我会在这里得到第二个意见。谢谢。

为了使问题保持​​“可回答” - 为任何用户重复使用相同的盐是否会减少可接受的最小保护以保持可搜索的密码历史记录(以防止 pswd 回收)?

【问题讨论】:

    标签: passwords history salt


    【解决方案1】:

    我可能在这里非常昏暗,但是,您将把盐存储在哪里,让有足够访问权限的人无法访问以获取散列密码。

    【讨论】:

    • 盐存储在散列密码旁边(可能在同一行),攻击者也得到它们,但需要花费大量时间来寻找匹配项(对于任何用户,或针对特定用户)。
    • 理论上,将它们分开并没有太多实际的附加值。盐的存在使得预先计算好的彩虹表变得毫无用处。所以现在有人必须从头开始计算一个新的彩虹表,增加盐的深度(以及使用盐的各种方式:前缀、后缀、拆分、隔行扫描等)。即使你知道盐,计算这个新表的时间和资源成本也太高了。总有一天,天网将开始计算和存储所有排列,但在它完成之前,或者我们将灭绝,这无关紧要。 ;-)
    【解决方案2】:

    首先,停止使用 MD5(如果你正在使用),使用 SHA-2、MD5、SHA-0 和 SHA-1,都是死哈希。

    -- 编辑:

    我现在同意 Jon Skeet 的观点,并建议您考虑在每次更改密码时生成新的盐。它涵盖了一个小案例,攻击者可能会获得盐+哈希,然后无法再次获得访问权限,但仍然允许他(对你如何组合它们进行一些猜测)计算未来所有可能的哈希值密码。它非常小,而且不是那么重要,因为密码大小需要非常小(比如 8 个字符),即使离线计算它们也很实用。然而它确实存在。

    其次,要考虑它是否重要,我们需要考虑盐的用途。这是为了防止对仅拥有完整密码列表的人进行离线攻击。

    在此基础上,如果在更改密码之前和之后同样“难以”获得盐,我认为没有用新盐(它和以前一样危险)。它增加了额外的复杂性,并且在实现复杂性时最容易出现安全问题。

    【讨论】:

    • 嗯“停止使用 MD5...并使用... MD5...” ;-) 是的,我对 MD5 的 refc 与“旧时代”一样,就像很久以前一样安全的。现在使用更好的东西,以及相当长的盐。攻击者也可以拥有(几乎总是拥有)盐的完整列表——不仅仅是密码。每次更改 salt 会使攻击者不得不为特定用户重新生成彩虹表,而不是重复使用它,这就是它有用的原因。
    【解决方案3】:

    重复使用相同的盐意味着如果用户明确成为黑客的目标,他们可以使用“用户的盐”生成“密码哈希”字典 - 这样即使用户更改了密码,黑客仍然会无需任何额外工作即可立即知道新密码。

    我每次都会使用不同的盐。

    至于存储 MD5 哈希加盐 - 大概您已经存储了盐 + 哈希,以验证用户的当前密码。为什么不能只保留完全相同的信息以进行历史检查?这样,您可以使用一段代码来进行密码检查,而不是分离当前路径和历史路径。他们在做同样的事情,所以他们使用相同的代码是有意义的。

    编辑:为了解释我的意思,考虑一个 4 个字符的盐,附加到密码......为了争论,假设有人在他们的密码中只使用 AZ、az 和 0-9(以及盐)。

    如果您不提前知道盐值(在准备字典攻击时),那么为了为所有 8 个字符的“人类”密码准备字典,您需要对 62^12 个连接密码进行哈希处理。但是,如果您总是知道连接密码的前 4 个字符是什么(因为您提前知道了 salt),那么您只需散列 62^8 个值即可 - 所有以 salt 开头的值。它使盐对特定的攻击毫无用处。

    这当然只适用于目标用户 - 并且只有当攻击者在密码更改之前和之后都可以访问哈希列表时。它基本上使更改密码作为一种安全措施变得不那么有效了。

    【讨论】:

    • 我看不出“攻击者”是如何知道新密码的。如果我有一个hash,即H(A+S),然后我得到新的hash:H(B+S),如何立即确定B?
    • @silky:如果您提前知道 S,则可以使用该盐准备字典攻击。它减少了要考虑的可能 (B+S) 值的数量。
    • 乔恩:很明显。但是攻击者是如何获得 S 而不是新的 S 的呢?如果他无法掌握新的 S,他是如何掌握散列密码的?我不认为这是一个现实的案例。
    • 他可以拿到新的 S - 但只有在密码更改之后。这意味着他必须在再次更改密码之前解决哈希问题。如果盐被重用,他可以解决 future 密码 before 密码更改的哈希。
    • @Jon -- 这几乎就是我的想法,但它涵盖了一个非常狭窄的案例,其中有人获得了用户数据表,专注于一个用户,然后继续频繁地获取用户数据表,或者在合适的时机重新做一遍。显得很苗条。但是,我继续构建代码,用所有以前的盐对新的 pswd 进行哈希处理,以与所有以前的哈希值进行比较。
    【解决方案4】:

    在密码哈希中使用盐的另一个原因是隐藏两个用户使用相同密码的事实(并不罕见)。使用不同的哈希值,攻击者将看不到这一点。

    【讨论】:

    • 问题是关于同一用户的历史哈希,而不是所有用户共享的。
    猜你喜欢
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 2011-01-09
    • 2014-06-09
    相关资源
    最近更新 更多