2009-10-07 132 views
20

我被要求对内部网站实施一些更改/更新;当他们称之为“未来证明”时。如何升级密码存储方案(更改散列算法)

我们发现,密码使用MD5算法散列。 (该系统自2001年以来一直在使用,因此在时间上已足够)。
我们现在想要将散列算法升级到更强的一个(BCrypt-hash或SHA-256)。

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

所以,我的问题是:

什么是接受的方式来改变散列算法,而无需访问明文密码?
最好的解决方案将是一个完全“幕后”的解决方案。

*)我们尝试;试图说服他们,我们用“密码时代”的说法,试图用咖啡来贿赂他们,试图与蛋糕,等等,等等贿赂他们,但它是不是一个选项

更新
我所期待的某种解决该问题的解决方案AUTOMAGIC的,但显然没有其他的选择不只是“等待用户登录,然后再转换”。

好了,现在我至少现在还没有其他可用的解决方案。

回答

24

首先,一个字段添加到数据库以识别密码是否被使用MD5或新算法。

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

- 在登录过程中,在那里你验证用户输入的密码:临时存储在内存中的用户提交的密码(无安全问题在这里,因为它已经在内存某处),并执行通常的MD5散列&与存储的散列进行比较;

- 如果提供了正确的密码(与现有的散列值相匹配),请通过新算法运行临时存储的密码,存储该值,更新新字段以确定此密码已更新为新算法。

(当然你只需使用新的算法为所有新用户/新口令。)

3

passwordChange时间字段添加到数据库中。

所有密码X日之前设置,检查使用MD5

所有密码一天后X设置,检查使用BCrypt或什么的。

+0

并且当他从MD5登录到BCrypt时更改用户的密码。 – Dennis 2012-11-09 11:15:19

3

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

+1

假设您在那时可以访问明文密码,您也可以让登录过程将密码“升级”到新的散列算法。 – Craig 2009-10-07 19:50:14

+1

D'oh!当然你可以,而且你应该。 – 2009-10-07 19:55:58

3

既然你不知道明文密码,也许你应该创建这表明encription版本的字段(如PasswordVersion bit default 0

下一次用户试图登录,使用当前版本的算法校验散列密码,就像你今天做。如果匹配,则再次对其进行散列并更新PasswordVersion字段。

希望你不需要PasswordVersion列大于bit。 =)

+0

“希望你不需要比位更大的PasswordVersion列”让我微笑(+1) – Jacco 2009-10-07 20:06:57

+0

真的,不要假设你这次是正确的。使用'byte'作为你的PasswordVersion。 – 2011-07-04 13:15:24

+1

只是8试图使它正确吗?使它成为'int',你将得到足够的空间来设置你自己的错误... =) – 2011-07-05 00:30:30

3

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

  1. 的算法标识。
  2. 服务器在首次计算并存储密码哈希时所选择的随机盐字符串。
  3. 使用指定算法连接salt +密码的哈希。

当然这可能只是一个分隔符一起存储在一个文本字段:

“SHA256:这-是盐:此结果,哈希值”

现在你现有条目转换为数值与空盐和老算法

“MD5 ::这 - 是最老的MD5哈希 - 没有盐”

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

  1. 如果你的数据库表明他们正在使用的旧算法,无盐,首先验证通过检查密码的MD5哈希值匹配旧密码。如果不是,则拒绝登录。
  2. 如果验证密码,请让服务器选择一个随机salt字符串,计算salt +密码的SHA256哈希值,并将新的密码表项替换为新算法salt和hash。
  3. 当用户再次登录时,您会看到他们正在使用新算法,因此计算salt +密码的哈希值并检查它是否与存储的哈希值匹配。

最终,在系统运行了适当的时间之后,您可以禁用尚未转换的帐户(如果需要)。

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

+0

旧的MD5方案已经使用了适当的哈希。 – Jacco 2009-10-07 21:13:26

+0

我不确定我是否理解你的评论,除非通过“used proper hashing”,你的意思是在用MD5散列密码之前已经添加了一个salt值。 如果是这样,升级方案仍然有效,您只需在使用MD5进行验证时考虑到salt。 – 2009-10-08 15:42:43

5

我不完全确定这个选项,因为我不是密码学方面的专家。请纠正我,如果我在这里有点错了!

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

......但是。有一个automagic解决方案 - 自己散列旧的哈希。也就是说,采用当前的哈希,并用更强大的算法再次哈希它们。注意,据我所知,在这里你不会从散列长度中获得任何附加的安全性,只有新算法增加的密码复杂性。

问题是,当然,检查密码然后必须通过这两个散列。你也必须为evey新密码做同样的事情。这是,很好,愚蠢。除非你想使用像Dave P.这样的解决方案,最终通过新的哈希算法回到单哈希密码中......在这种情况下,为什么还要为此烦恼呢?

不过,这是一个选项,可以 - (在介绍企业西装方式,具有相对着脸......当然,你可以使用它在一个华丽的“安全性提高了所有密码,立即生效!”)立即应用于所有当前密码,而无需任何逐步迁移阶段。

但是,男孩,哦,男孩,稍后有人会有一个很好的笑看这个代码! :)

+0

这听起来像我正在寻找的东西。但我不确定'散列哈希'的含义,我认为我在某些地方看到结果在某些条件下可能是次优的。但我不知道。 – Jacco 2009-10-19 12:27:37

+1

这是一个坏主意,因为如果在第一个散列中存在冲突,那么在组合算法中会有冲突。在MD5中有已知的碰撞。 – 2011-07-04 13:17:05

+2

@Richard,为什么在这种情况下哈希碰撞很重要? – 2011-07-05 05:40:44