当前位置: 首页 > 知识库问答 >
问题:

将旧密码移动到新的哈希算法?

姚航
2023-03-14

我正在将一个站点切换到rails。这是一个拥有5万用户的大型网站。问题是,现有的密码哈希方法非常弱。我有两个选择:

1)切换到一个新的算法,为每个人生成随机密码,然后将这些密码通过电子邮件发送给他们,并要求立即更改

2)实现新算法,但使用旧算法,然后对结果进行哈希。例如:

密码:abcdef=算法1=

任何新密码都需要经过原始算法(md5),然后对结果进行哈希运算,如果这有意义的话?这有什么不利之处吗?

共有3个答案

姬成荫
2023-03-14

您可以为所有使用新密码方法更新密码的用户创建一个新密码字段,只需使用选项2更新所有用户即可。

结合使用旧密码方法的所有用户在登录时强制更新密码,将自动将所有活动用户移动到新密码方法。

易淳
2023-03-14

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

此方法的一个变体是将哈希类型存储为哈希字符串的一部分。只要您可以明确地区分不同的散列格式,这种方法也同样有效,而且它的优点是,您还可以在同一个字符串中包含任何其他所需的参数(例如用于键拉伸的salt和功因子),而无需为每个参数向数据库中添加额外的字段。

例如,这是现代Unix crypt(3)实现(以及各种高级语言(如PHP)中的相应函数)通常使用的方法:基于DES的经典密码散列(非常弱)看起来像abJnggxhB/yWI,虽然(稍微)更现代的散列可能看起来像$1$z75qouSC$nnvpak1ftd0yvd62sjr1,其中1指定了散列方法,z75qouSC是盐,nnvpak1ftd0yvd62sjr1是实际的散列,而选择分隔符$,因为它不能出现在旧式DES散列中。

您建议的方法,其中新哈希的计算如下:

 hash = new_hash( old_hash( password ) )

在某些情况下可能很有用,因为它允许更新所有现有记录,而无需等待用户登录。然而,只有当旧的哈希函数保留足够的密码熵时,它才是安全的。

例如,即使是一个相当旧且弱的密码哈希函数,如未加盐的MD5,也足够好了,因为它的输出依赖于整个输入,并且具有高达128位的熵,这比几乎任何密码都要多(而且绰绰有余无论如何,要抵御蛮力攻击)。另一方面,试图使用基于DES的旧密码(3)函数作为旧哈希来应用这种结构将是灾难性的,因为旧密码(3)将忽略除每个密码的前8个字符(以及偶数的最重要位)之外的所有字符那些字符)。

郑博厚
2023-03-14

通常不需要重置密码,只需等待用户下次登录即可。

  1. 首先尝试用新算法验证输入的密码。新密码和已转换的密码将不需要更长的时间进行验证

每个密码存储系统都必须有切换到更好的哈希算法的选项,您的问题不是一次性迁移问题。像BCrypt这样的好的密码散列算法有一个成本因素,有时你必须增加这个成本因素(因为更快的硬件),然后你需要与迁移完全相同的过程。

如果你的第一个算法真的很弱,并且你想立即提供更多的保护,那么你的选项2对旧哈希进行哈希是一件好事。在这种情况下,您可以计算双哈希,并用新的双哈希替换数据库中的旧哈希。

$newHashToStoreInTheDb = new_hash($oldHashFromDb)

您还应该标记这个密码散列(请参阅原因),以便将其识别为双散列。这可以在单独的数据库字段中完成,也可以包含自己的签名。现代密码散列函数还包括算法的签名,这样它们就可以升级到新的算法,并且仍然可以验证旧的散列。该示例显示了BCrypt哈希的签名:

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

验证将这样运行:

  1. 决定它是否是双散列。
  2. 如果它是一个新的哈希,调用新的哈希函数来验证输入的密码,你就完成了。
  3. 如果是双哈希,则将其与双哈希算法new_hash(old_hash($密码))进行比较。
  4. 如果双哈希值匹配,那么您可以计算并存储新哈希。
 类似资料:
  • 问题内容: 我正在尝试从位于slicehost(两个不同的托管公司)的服务器中的php脚本连接到dreamhost上的mysql服务器。我需要这样做,以便可以将slicehost上的新数据传输到dreamhost。使用转储不是一种选择,因为表结构不同,我只需要传输一小部分数据(每日记录100-200条),问题是我在slicehost和dreamhost上使用了新的MySQL密码哈希方法使用旧的,所

  • 每个人在建构 PHP 应用时终究都会加入用户登录的模块。用户的帐号及密码会被储存在数据库中,在登录时用来验证用户。 在存储密码前正确的 哈希密码 是非常重要的。密码的哈希操作是单向不可逆的,该哈希值是一段固定长度的字符串且无法逆向推算出原始密码。这就代表你可以哈希另一串密码,来比较两者是否是同一个密码,但又无需知道原始的密码。如果你不将密码哈希,那么当未授权的第三者进入你的数据库时,所有用户的帐号

  • 我是在阅读了一些关于php中会话管理的主题后开始进行安全讨论的,请查看:https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-termer-persistence#title.2 引自章节:胡椒还是不胡椒? 一个更好的解决方案是,在将散列插入数据库之前对其进行加密,如果使用硬件分离,这种解决方案尤其有用。有了这

  • 多亏了最近一篇文章中的一些好建议,我才从中实现了PBKDF2https://defuse.ca/php-pbkdf2.htm进入一个小的PHP图像库,我正在建设教自己一些PHP。 我知道您将salt和hash存储在数据库中,然后在用户输入密码时重新构建它们以匹配。我不明白的是,当上面网站上的validate_password函数为同一个密码生成不同的、唯一的salt时,它是如何工作的。 例如,我创

  • 我刚刚讨论了散列码的概念,遇到了一行:

  • 行动时间 - 哈希我们的密码 我们将在此部分中使用更安全的哈希密码AVP替换用户文件中的Cleartext-Password AVP。 关于如何创建和呈现散列密码似乎存在一般性的混淆。 我们将帮助您澄清此问题,以便为每种格式生成工作哈希值。 OpenLDAP常见问题解答是帮助我们处理哈希值的有价值的URL: http://www.openldap.org/faq/data/cache/419.ht