我有一个使用MD5进行盐渍和散列的旧密码数据库。我想更新系统,以便数据更安全。
第一个选项是在用户登录并在一段时间后停用旧用户时将用户转换为新的哈希方案(Salt + Scrypt或PBKDF2 HMACSHA256),这样他们就必须使用密码恢复功能,该功能会自动更新他们的哈希。
允许我立即升级所有人的另一个选项是采用现有的MD5哈希值,为每个哈希值添加一个新的随机盐值,然后使用新的哈希方案(Salt + Scrypt或PBKDF2 HMACSHA256)对结果进行哈希处理,将该值存储到数据库并删除旧值。
然后当用户登录时,我将不得不应用旧方法,然后应用新方法。我更喜欢第二个选项,因为它允许我尽早从数据库中删除所有旧的不安全哈希值。
盐是否安全并重现现有的哈希? MD5是如此破碎以至于我可以运行脚本来解密密码并使用新方案重新散列它们吗?
或许最好的解决方案是两种选择的组合?这样我就不必在数据库中保留现有的MD5哈希不安全状态,我可以将用户迁移到新系统一段时间吗?
答案 0 :(得分:5)
MD5并没有破坏你可以轻松解除所有密码的干扰,但假设密码的质量不是很好,那么你可能会强制它们并将它们转换为新的,更安全的格式。 MD5的破碎是由于它相对较小的长度(更多的碰撞表面)和计算上简单的计算(意味着暴力攻击比具有更大运行时复杂度的算法(如SHA2)更可行)
如果我是你,我会做你列出的两种方法(因为正如你所提到的,如果你的数据库遭到黑客攻击,快速移动密码很重要)。首先,我会强制所有暴力强制MD5密码并将它们转换为新格式。我在过去做过这个,到目前为止最好的结果是使用HashCat(Cuda或OCL风味,因为他们使用GPU并且速度提高了200倍)。如果Hashcat太难(学习曲线可能很陡),那么试试John the Ripper。它比HashCat慢很多,但使用起来要容易得多。
对于无法破解的密码,请暂停用户的帐户并让他们重置密码。或者为了更好用户,只需在下次登录时通过发送两个哈希值将数据库中的密码更新为新格式。如果MD5签出,则销毁它并用新格式替换它。这些只是一些想法。
编辑:
忘了提一下,如果你想将MD5密码哈希到新的格式,这种格式在安全方面会很好,虽然它会给你的代码增加另一层复杂性,并且在复杂性存在的情况下还有实施的空间缺陷。只是想一想。
答案 1 :(得分:1)
这实际上是一个非常巧妙的想法。通常我会:
仅使用MD5的缺点是它易于暴力破解。通过(临时)将MD5结果作为应用真实scrypt / Argon2之前的中间步骤处理,可以阻止强制尝试。
在"真实" 密码哈希之前使用快速哈希算法作为预处理步骤并非闻所未闻 - 甚至可能有用。
因此,使用预哈希(虽然不一定是MD5)可能有一个优点。
我不知道您目前如何存储MD5哈希值。 MD5是128位。假设您将其存储在Base64中,您可以轻松识别它:
nMKuihunqT2jm0b8EBnEgQ==
期望的最终目标就像scrypt:
nMKuihunqT2jm0b8EBnEgQ==
$s0$e0801$epIxT/h6HbbwHaehFnh/bw==$7H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0=
因此,在针对已保存的哈希验证凭据时,您可以确定它是哪个哈希并使用适当的算法。您的中间步骤增加了计算复杂性,它定义了您自己的格式:
MD5 + scrypt
类似的东西:
nMKuihunqT2jm0b8EBnEgQ==
$md5s0$e0801$eX8cPtmLjKSrZBJszHIuZA==$vapd0u4tYVdOXOlcIkFmrOEIr1Ml2Ue1l2+FVOJgbcI=
$s0$e0801$epIxT/h6HbbwHaehFnh/bw==$7H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0=
现在您可以根据保存的哈希识别正在使用的算法,并且可以分段升级密码。