如何升级密码存储方案(更改散列算法)

时间:2009-10-07 19:40:50

标签: security password-protection password-hash

我被要求对Intranet网站实施一些更改/更新;让它成为'未来证明',因为他们称之为。

我们发现使用MD5算法对密码进行哈希处理。 (该系统自2001年以来一直存在,所以它足够了) 我们现在想要将散列算法升级为更强的算法(BCrypt-hash或SHA-256)。

我们显然不知道明文密码,为用户群创建新密码不是选项 *)

所以,我的问题是:

在不访问明文密码的情况下,更改散列算法的可接受方法是什么?
最好的解决方案是完全“幕后”的解决方案。

<子> *) 我们尝试了;试图说服他们,我们使用了'密码年龄'的论点,试图用咖啡贿赂他们,试图用蛋糕贿赂他们等等。但它不是一个选择

更新
我希望有一些解决问题的自动解决方案,但显然除了'等待用户登录,然后转换'之外没有其他选择。

好吧,至少现在我现在还没有其他解决方案。

7 个答案:

答案 0 :(得分:28)

首先,在数据库中添加一个字段,以确定密码是否使用MD5或新算法。

对于仍在使用MD5的所有密码:

- 在登录过程中,您验证用户输入的密码:暂时将用户提交的密码存储在内存中(这里没有安全问题,因为它已经存储在内存中)并执行通常的MD5哈希&amp;与存储的哈希进行比较;

- 如果给出了正确的密码(与现有哈希匹配),则通过新算法运行临时存储的密码,存储该值,更新新字段以识别此密码已更新为新算法。 / p>

(当然,您只需将新算法用于任何新用户/新密码。)

答案 1 :(得分:6)

我不完全确定这个选项,因为我不是加密专家。如果我在某处错了,请纠正我!

我认为Dave P.显然是最好的选择。

......但是。有一个自动化的解决方案 - 哈希老哈希自己。也就是说,获取当前哈希值,并使用更强大的算法再次哈希它们。请注意,据我所知,这里没有从哈希长度获得任何额外的安全性,只增加了新算法的加密复杂性。

问题是,当然,检查密码必须经过两个哈希。而且你也必须为evey新密码做同样的事情。这就是,嗯,非常愚蠢。除非你想使用像Dave P.这样的类似方案解释最终用新哈希算法重新使用单哈希密码...在这种情况下,为什么甚至打扰这个呢? (当然,你可以在一个华而不实的“改进所有密码的安全性,立即应用!”中使用它 - 在演示公司套装的方式,相对直面......)

不过,它是一个可以立即应用于所有当前密码的选项,没有任何逐步迁移阶段。

但男孩,噢,小男孩,以后会有一个好笑的人看着那段代码! :)

答案 2 :(得分:3)

将passwordChange datetime字段添加到数据库中。

在第X天之前设置的所有密码,使用MD5检查

在第X天之后设置所有密码,使用BCrypt或其他任何方式进行检查。

答案 3 :(得分:3)

您可以在哈希字段本身(例如“MD5:d41d8cd98f00b204e9800998ecf8427e”)或另一列中存储,该算法用于创建该哈希。然后,您必须修改登录过程以在检查密码时使用正确的算法。当然,任何新密码都将使用新算法进行哈希处理。希望密码最终到期,并且随着时间的推移,所有MD5哈希都将被逐步淘汰。

答案 4 :(得分:3)

由于您不知道明文密码,也许您应该创建一个表示登记版本的字段(如PasswordVersion bit default 0

下次用户尝试登录时,请使用当前算法版本检查散列密码,就像您今天所做的那样。如果匹配,请再次哈希并更新PasswordVersion字段。

希望您不需要大于PasswordVersion的{​​{1}}列。 =)

答案 5 :(得分:3)

您应该更改密码数据库以存储3个项目:

  1. 算法标识符。
  2. 服务器在首次计算并存储密码哈希值时选择的随机盐字符串。
  3. 使用指定算法连接salt +密码的哈希值。
  4. 当然,这些可以只用一个分隔符存储在一个文本字段中:

      

    “SHA256:这-是盐:此-是散列值”

    现在将现有条目转换为具有空盐和旧算法的值

      

    “MD5 ::这-是最老-MD5散列-无盐”

    现在您有足够的信息来验证所有现有的密码条目,但您也可以验证新条目(因为您知道使用了哪个哈希函数)。您可以在下次现有用户登录时将旧条目转换为新算法,因为在此过程中您将拥有其密码:

    1. 如果您的数据库表明他们使用的是没有salt的旧算法,请首先通过检查密码的MD5哈希是否匹配来验证密码。如果没有,请拒绝登录。
    2. 如果密码已经过验证,请让服务器选择一个随机盐字符串,计算salt +密码的SHA256哈希值,并用新的密码表条目替换新的算法,盐和哈希值。
    3. 当用户再次登录时,您会看到他们正在使用新算法,因此请计算salt +密码的哈希值并检查它是否与存储的哈希匹配。
    4. 最后,在此系统运行一段合适的时间后,您可以禁用尚未转换的帐户(如果需要)。

      添加每个条目唯一的随机盐字符串使得该方案对使用彩虹表的字典攻击更具抵抗力。

答案 6 :(得分:0)

最佳答案是来自实际的密码学专家 https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016#legacy-hashes

这篇文章还有助于说明您应该使用哪种哈希。即使显示“ 2016”,它仍然是当前的。如果有疑问,请使用bcrypt。

在用户帐户表中添加一列,称为legacy_password(或等效名称)。这只是一个布尔

计算现有密码哈希的新的更强哈希,并将其存储在数据库中。

修改身份验证代码以处理旧式标志。

当用户尝试登录时,首先检查是否设置了legacy_password标志。如果是这样,请先使用旧的密码哈希算法预哈希他们的密码,然后使用此预哈希值代替他们的密码。然后(md5),重新计算新的哈希并将新的哈希存储在数据库中,并在此过程中禁用legacy_password标志。