我可以通过加盐现有的MD5哈希来提高MD5哈希密码的安全性,并使用scrypt或pbkdf2 hmacsha256哈希结果吗?

Can I improve the security of MD5 hashed passwords by salting the existing MD5 hash and hash the result using Scrypt or PBKDF2 HMACSHA256?

我有一个旧密码数据库,使用MD5对其进行了salt和hash处理。我想更新系统,使数据更安全。

第一个选项是当用户在一段时间后登录并停用旧用户时,将其转换为新的哈希方案(salt+scrypt或pbkdf2 hmacsha256),因此他们必须使用密码恢复功能,该功能将自动更新其哈希。

另一个允许我立即升级所有人的选项是,使用现有的MD5散列,向每个散列添加新的随机salt值,然后使用新的散列方案(salt+scrypt或pbkdf2 hmacsha256)散列结果,并将该值存储到数据库中并删除旧值。

然后当用户登录时,我要先应用旧方法,然后再应用新方法。我更喜欢第二个选项,因为它允许我尽早从数据库中删除所有旧的不安全哈希。

对现有的大麻进行加盐和再加热是否安全?MD5是否如此中断,以至于我可以运行一个脚本来解散列密码并使用新方案重新刷新它们?

或者最好的解决办法是把这两种方法结合起来?这样我就不必让数据库中现有的MD5散列不受保护,我可以将用户迁移到新系统一段时间?


MD5没有那么坏,你可以很容易地去散列所有的密码,但假设密码的质量不太好,那么你可能会蛮干他们,并将他们转换成新的,更安全的格式。MD5的破碎是因为它的长度相对较小(碰撞面较多),计算简单(这意味着暴力攻击比具有更大运行时复杂性的算法(如sha2)更可行)。

如果我是你,我会做你列出的两种方法(因为正如你提到的,快速转移密码是重要的,以防你的数据库被黑客攻击)。首先,我将强制所有暴力的MD5密码,并将其转换为新的格式。我以前做过这个,到目前为止最好的结果是使用hashcat(最好是CUDA或OCL口味,因为它们使用GPU,速度快200倍)。如果hashcat太难(学习曲线可能很陡),请尝试开膛手john。它比hashcat慢得多,但使用起来容易得多。

对于无法破解的密码,请终止用户帐户并让他们重置密码。或者,为了更好地保护您的用户,只需在他们下次登录时通过发送两个哈希值将数据库中的密码更新为新格式即可。如果MD5签出,则将其销毁并用新格式替换。这些只是一些想法。

编辑:

忘记提到,如果您只想将MD5密码散列为新的格式,这将是非常好的安全性,尽管它为您的代码增加了另一层复杂性,并且在有复杂性的地方存在实现缺陷的空间。只是想一想。


这实际上是一个非常巧妙的想法。通常我会:

  • 等待用户返回
  • 意识到他们存储的密码需要更新
  • 现在我在内存中有了他们的(已知有效的)密码:用新算法重新刷新它
  • 将新哈希存储在数据库中

只使用MD5的缺点是很容易进行野蛮变形。通过(暂时)在应用真正的scrypt/argon2之前将MD5结果作为一个中间步骤处理,您将阻止野蛮的尝试。

在"真正的"密码散列之前,使用快速散列算法作为预处理步骤是闻所未闻的,甚至是有用的。

  • bcrypt的已知密码长度限制为72字节(71个utf-8字符,然后是一个空终止符)。Dropbox在通过bcrypt运行之前将sha2-512应用于传入的明文密码。通过首先通过哈希运行长密码,他们克服了71个字符的限制。
  • 这不仅克服了密码长度限制(避免截断或限制密码大小),而且还可以防止在有人提供超长密码时发生拒绝服务攻击。bcrypt和scrypt可能会受到较长密码的攻击(我不知道argon2)。

因此,使用预哈希(尽管不一定是MD5)有一个优点。

我不知道您当前如何存储MD5哈希。MD5是128位。假设您将它存储在base64中,您可以很容易地识别它:

  • MD5:nMKuihunqT2jm0b8EBnEgQ==

期望的最终目标类似于scrypt:

  • MD5:nMKuihunqT2jm0b8EBnEgQ==
  • 加密:$s0$e0801$epIxT/h6HbbwHaehFnh/bw==$7H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0=

因此,当根据保存的哈希验证凭证时,您可以确定它是哪个哈希,并使用适当的算法。中间步骤(增加了计算复杂性)正在为以下内容定义自己的格式:

MD5 + scrypt

类似:

  • MD5:nMKuihunqT2jm0b8EBnEgQ==
  • MD5+加密:$md5s0$e0801$eX8cPtmLjKSrZBJszHIuZA==$vapd0u4tYVdOXOlcIkFmrOEIr1Ml2Ue1l2+FVOJgbcI=
  • 加密:$s0$e0801$epIxT/h6HbbwHaehFnh/bw==$7H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0=

现在,您可以根据保存的哈希识别正在使用的算法,并可以分块升级密码。