如何将我的旧 sha1 密码更改为数据库字段中的 sha256 或 Bcrypt 值

How to change my old sha1 passwords to sha256 or Bcrypt values in database field

我有一个数据数据库,其中密码列使用 sha1 值。我打算将我的加密方法更新为 Bcrypt 或 sha256。想要获得一个脚本,它将所有 sha1 密码更新为 sha256 或 Bcrypt 值。非常感谢

示例: 如果我的密码是 hari

sha1 给出

46ebaaa2b80c7a3459b80353e085aaeed5aff2ff

sha256 给出

f7b3781c5eafc2779a96bae2e4875a83ecce46f198e9f81916521d9d218c7da7

我怎么把sha1全部改成sha256

无法更改哈希值,因为哈希操作不可逆。也就是说,您可以将纯文本转换为哈希值,但不能反过来。
因此,更好的办法是为 sha256 密码设置一个不同的 table。并在下次登录时继续将您的用户移植到其他 tables。
即,下次用户登录时,检查现有 table 中的密码是否正确。如果发现用户是正确的,则使用 sha256 重新散列密码并将其保存到另一个(新)table。这样最终,当用户登录时,您可以将它们移植到更安全的 sha256 哈希密码。
移植用户后,您可以从旧的 table 中删除他们的条目(在那个时刻/之后通过任何批处理脚本)。

现在介绍如何处理登录。在移植所有用户之前,这将是一个两步过程。
1.先签入较新的table。如果没问题,就继续吧。
2. 否则检查旧的 table。

其他回答或评论中已经说了很多。

基本上,您不能简单地从一个散列值移动到与初始值相对应的另一个散列值。哈希函数是一种单向函数。

但不要害怕,还有希望!这是一种方法,可以让您:

  • 添加新的密码哈希算法
  • 避免重置所有用户的密码
  • 处理遗留密码哈希算法
  • 立即使用新的哈希算法保护旧密码

选择哈希函数

这很重要。请仔细阅读。

对于密码存储,您应该使用任何(加密)散列函数,如 SHA1、SHA2 甚至 SHA3 (Keccak)。主要原因是它们速度快。太快。这不是您应该通过密码散列而茁壮成长的东西。 More information.

而且他们不处理加盐,这意味着您将需要手动执行此操作,这意味着您更有可能搞砸它。

对于密码存储,您需要一个密码散列函数,用于此目的。你有几个众所周知的功能:PBKDF2、BCrypt、SCrypt 或 Argon2。

这些函数可以处理盐并且速度很慢(并且性能可以通过参数调整)。

既然您正在使用 PHP,这对您来说就更简单了。 password_hash() 函数为您提供了一个漂亮且有效的 BCrypt。用它!

如果您使用 PHP 7.2+,它甚至支持 Argon2。但现在坚持使用 BCrypt。它更简单且经过实战检验。

BCrypt 的主要问题是配置其参数:cost 值。它直接影响计算单个散列所需的时间。

基本上,这取决于您的服务器。所以你需要在这里做一些测试,从默认成本 10 开始,直到计算哈希值需要 700 毫秒到 1 秒。

我做了 this handy PHP script some times ago to help me in this task. I also made one for for Argon2,但如您所见,它更复杂。

此外,切勿提供自己的盐。让函数为您处理(即使您认为可以做得更好)。


实施新的密码哈希算法

如某些评论所述,最好的方法是添加一个新的布尔值列 legacy_pwd,并初始化为 true。

编辑当然不要忘记更新关于列大小的table定义。 SHA1 摘要的大小为 40 个十六进制字符(160 位),而 BCrypt 摘要的大小为 60 个字符。

此外,为了立即保护您现有的客户密码,我建议您将新的哈希函数 (BCrypt) 应用于 password 列。

当用户尝试使用其 username/password 登录时,您首先检查 legacy_pwd

如果legacy_pwd为真,取bcrypt(sha1("plain_text_pwd"))并将其与数据库中的一个商店进行比较。如果匹配,存储 bcrypt("plain_text_pwd"),将 legacy_pwd 设置为 false 并让用户登录。

如果 legacy_pwd 为假,只需取 bcrypt("plain_text_pwd") 并将其与数据库中的一个商店进行比较。如果匹配,则让用户登录。


跟进和清洁

通常,您需要检查 legacy_pwd 是否还有剩余的 true 值。如果不是(所有用户都已迁移),您可以删除该列并删除处理旧密码的代码。