将旧的密码,以新的散列算法?(Moving old passwords to new hashing

2019-07-18 09:22发布

我切换站点到轨道上。 这是一个相当大的网站有50K +用户。 问题是,现有的密码散列法是极其微弱的。 我有两个选择:

1)切换到新的算法,生成每个人的随机密码,然后通过电子邮件发送的密码,并立即要求该变更后

2)实施新的算法,但用旧前,然后散列结果。 例如:

密码:ABCDEF =算法1 => xj31ndn =算法2 => $ 21aafadsada214

任何新的密码,将需要经过原始算法(MD5),然后有一个散列的结果如果让任何意义吗? 有没有缺点呢?

Answer 1:

通常情况下,没有必要重置密码,一个可以只等到下一次用户登录。

  1. 第一次尝试用新的算法,以验证所输入的密码。 新密码和已完成转换的密码不会需要更长的时间进行验证即可。
  2. 如果不匹配,与旧的哈希算法进行比较。
  3. 如果旧的散列值匹配,那么你可以计算和存储新的哈希,因为你知道密码即可。

每个密码存储系统必须切换到一个更好的散列算法的选项,你的问题不是一次性的迁移问题。 良好的密码哈希算法,如BCrypt有一个成本因素,从时间到时候你一定要增加这个成本因素(因为更快的硬件的),那么你需要的完全相同的过程,因为你需要进行迁移。

你选择2散列老哈希是一件好事,如果你的第一个算法是非常弱的,你要马上给更多的保护。 在这种情况下,你可以计算出双哈希值,并与新的双哈希数据库取代旧的哈希值。

$newHashToStoreInTheDb = new_hash($oldHashFromDb)

你也应该纪念这个密码散列( 知道为什么 ),这样你就可以将其识别为双哈希值。 这可以在一个单独的数据库字段来实现,也可以包括您自己的签名。 现代密码散列函数还包括算法的签名,让他们可以升级到较新的算法,而且还可以验证旧的哈希值。 该示例示出了BCrypt散列的签名:

$2y$10$nOUIs5kJ7naTuTFkBy1veuK0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
___
 |
 signature of hash-algorithm = 2y = BCrypt

验证将运行这样的:

  1. 决定它是否是双哈希值。
  2. 如果它是一个新的哈希,调用新的哈希函数来验证所输入的密码,就大功告成了。
  3. 如果是双散列,使用双散列算法进行比较new_hash(old_hash($password))
  4. 如果双散列值匹配,那么你可以计算和存储新的哈希值。


Answer 2:

最简单的解决方案可能是一个“密码哈希类型”列添加到数据库中。 设置它最初的“老”; 当用户使用新的算法,并将数据库类型为“新的”,再哈希登录密码。

这种方法的一个变型是哈希类型存储作为散列字符串的一部分 。 该作品一样好,只要你能明确告诉不同的hash格式分开,并具有的优点是,你还可以包括任何其它需要的参数(如盐和工作因素关键拉伸 )在相同的字符串,不无需添加额外的字段为每个到数据库。

例如,这是通常使用的方式现代化的Unix的crypt(3)实现 (和在各种高级语言,如相应的功能PHP ):一个典型的基于DES(和可怕弱)密码哈希会看起来像abJnggxhB/yWI ,而(略)更现代的哈希可能看起来像$1$z75qouSC$nNVPAk1FTd0yVd62S3sjR1 ,其中1所指定的散列方法, z75qouSC是盐和nNVPAk1FTd0yVd62S3sjR1实际哈希,和分隔符$选择,因为它不能在OLD-出现风格DES哈希值。


你建议的方法,在新的散列计算公式为:

 hash = new_hash( old_hash( password ) )

可以在某些情况下非常有用,因为它允许所有现有的记录,而不必等待用户登录进行更新。但是,如果旧的散列函数保留足够的密码熵的只是安全的。

例如,即使一个相当老,弱加密散列函数,如无盐MD5 ,就不够好,因为它的输出取决于整个输入并拥有高达熵,这几乎比任何密码,将会有更多的128位(和以上足以抵御蛮力攻击,反正)。 在另一方面,试图使用旧的基于DES加密中应用这种结构(3)功能作为老哈希将是灾难性的 ,因为旧的crypt(3)将全部忽略,但每个密码的前8个字符(以及即使这些字符是最显著位)。



Answer 3:

您可以创建一个新的密码字段已用新密码更新方法,其密码的所有用户,并只与您的选项2更新大家。

与强制密码更新上登录的所有用户使用旧密码方法会自动所有活动用户迁移到新的密码方法相结合这一点。



Answer 4:

另一种可能是保留两个哈希值可用于在数据库中单独列迁移阶段:

  • 如果新的哈希值不登录时,则检查与旧散列,并保存新的散列并删除旧的哈希值。
  • 如果新的散列存在,只能用这个来验证。

因此,一段时间后,你将只剩下新的哈希 - 至少在谁至少一次登录的用户。



文章来源: Moving old passwords to new hashing algorithm?