如何在不影响安全性的情况下升级实时数据库的哈希方法?

信息安全 哈希 数据库
2021-08-20 01:16:40

我正在开发一个可从外部访问的 Intranet 项目。密码以普通的 Hash 和 salt 方法存储在 Sql Server 数据库中。问题在于哈希算法。

它目前使用 SHA512Cng,我们找不到使用该算法的原因。我想升级这个散列算法以使用 bcrypt以及使盐密钥更长。

当然,由于密码是经过哈希处理的,我们只是不能运行批处理来升级密码。

将身份验证方法从不太安全的方法升级到更安全的实时数据库时,可能的路径是什么?

当然,我们希望数据库保持与当前提供的 SHA512Cng 方法一样安全,并且在升级过程中不会危及数据库。

4个回答

我建议在每个用户下次登录时逐步将其切换到新的密码散列方法。那时,你知道他们的明文密码,所以你可以用 bcrypt 重新散列它并将它们切换到 bcrypt。这避免了“国旗日”或联系所有用户的需要。事实上,它对用户是不可见的:您的用户永远不需要知道您正在转换到新的密码哈希算法。

更详细地说:

  • 向数据库添加另一个字段以指示使用哪种散列算法来计算密码散列。换句话说,每个用户都有两个字段:一个用于密码哈希,一个用于指示哈希算法(SHA512Cng 或 bcrypt)。最初,每个用户的密码哈希算法被初始化为 SHA512Cng。

  • 当用户尝试登录时,查找他们帐户的密码哈希算法,使用该算法对他们提供的密码进行哈希处理,并将其与存储的哈希值进行比较。如果不匹配,则拒绝登录。如果它们匹配,则接受登录。

  • 此外,如果登录被接受并且数据库中的算法是 SHA512Cng,则使用 bcrypt 重新散列密码,用新的 bcrypt 散列覆盖密码散列,并将数据库中的算法更改为 bcrypt。

这使您可以在人们登录您的服务时逐渐过渡到新的密码哈希算法。

或者,几个月后,如果有任何用户尚未登录(因此他们的密码仍然使用 SHA512Cng 进行哈希处理),您可以重置他们的密码或通过电子邮件发送给他们并要求他们再次登录或其他什么。但是,在许多情况下,这可能不是必需的。

PS 或者,您可以使用 Ramhound 的简单 bcrypting 密码哈希的优雅解决方案。聪明的!

散列哈希,然后在用户成功验证或更新密码时更新。这样你就有了直接的安全感,这是你努力的重点。

执行:

散列并将所有 SHA 散列保存在带 bcrypt 的 db 中,因此您只有 bcrypt 散列。当用户进行身份验证时,您检查是否与 bcrypt(password) 等效。如果失败,然后与 bcrypt(sha512(password)) 进行比较。当用户成功验证和/或更新他们的密码时,您可以使用 bcrypt 对密码进行哈希处理。

主要的权衡是您必须维护几行额外的代码(二级哈希比较)。但这比在保留不安全的散列密码的同时维护第二个密码列要好得多。

编辑:啊!在注意到 Ramhound 在对该问题的评论中回复了相同的想法之前发布。同意他的意见。

通用方法是使用一个过渡时期,在此期间同时使用旧的和新的哈希方法;这需要能够区分数据库中两种类型的哈希。然后可以在用户下次登录时将哈希方法从旧的升级到新的。您可以轻轻推动用户,以便他们在接下来的几个月内登录;或者,您可以禁用六个月未登录的人的帐户。有关详细信息,请参阅此问题

仍然在过渡期间,您可以链接哈希:使用旧哈希值作为新哈希值的“密码”。如果旧函数是密码的普通、未加盐的哈希,那么这将很容易。如果旧函数使用盐,那么您需要将它与新函数的新盐一起保留。

理想情况下,您会使用一个经过加盐和迭代的哈希函数,这样就可以在不需要原始密码的情况下添加额外的迭代。据我所知,不存在支持这一点的广泛的密码散列函数,尽管我认为没有直接的可能性(密码学家仍有工作要做)。

通常的方法是联系用户,让他们知道他们需要登录,比如在下个月内,然后当他们这样做时,升级哈希值。

这样,除了在用户登录时确认用户的旧密码散列并存储新密码的散列之外,您不需要做任何事情。

您所需要的只是跟踪哪些用户已升级,并删除旧的哈希值。