security - 重新散列使用过时函数散列的现有密码

标签 security hash passwords

我们有一个使用 MS 成员(member)资格提供程序存储密码的旧系统,并且刚刚发现它仅使用带有随机盐的 SHA1 来存储密码,因此显然我们对这种情况感到担忧。我知道理想的情况是强制全局密码重置,但出于各种原因,我们希望尽可能避免这种情况,并按原样保留现有密码。我已经做了一些探索并设法找到了一些源代码,并且可以重新散列我的密码,这样我就得到了与它的存储版本相同的结果,所以我想重写所有适当的方法来重新实现以安全的方式编写代码。

我建议做的是使用当前“安全”哈希重新哈希存储的密码(AFAIK,由于暴力破解密码所需的计算时间量,当前方法仅被归类为安全,所以如果系统获得重大性能升级,整个编程世界最终可能不得不重新审视这一点),然后将此哈希值包装在代码中现有的哈希值周围,但我有两个问题:-

这真的安全吗?据我所知,每个哈希都需要增加熵的量,我 90% 确定这会这样做,但是这样做有什么我需要注意的问题吗?我还猜测,在散列链中,它是决定“基线”安全级别的最强散列函数,但我想我应该仔细检查散列“不安全”散列时是否存在任何奇怪的数学怪癖。我确信不是,但由于问题的性质,我宁愿问一个愚蠢的问题,也不愿做出任何错误的假设,因为哈希函数的技术方面并不是我真正研究过的内容。

在重新散列之前,我应该将盐重新应用于当前散列吗?我对此的想法是,如果存在现有的计算表,可以将旧的哈希值转换为新的哈希值——以防万一有人做了一些繁重的工作来试图绕过这个方法。我相信 b-crypt 可能已经包含盐,但如果我使用不包含盐的替代品,我猜应该包含一个盐?

最佳答案

如果您等不及下次用户登录并且不想强制登录,则双重哈希可能是立即保护非常弱的密码哈希的好方法。弱密码哈希包括无盐哈希或非常快的哈希,例如 SHA-*/MD5。

因此您可以像这样准备数据库:

  1. 使旧的盐持久化在数据库中,您需要 oldSalt验证双重哈希。
  2. 计算双散列并将其存储在数据库中 newHash = newSafeHashFunction(oldHash, newSalt) 。目前安全的哈希函数有 BCrypt、SCrypt、Argon2 和 PBKDF2。生成满足新密码哈希函数要求的新盐。
  3. 下次成功登录后,应将双哈希替换为纯新算法 newSafeHashFunction(password, newSalt) .

大多数密码哈希实现都会自行生成安全盐并将其包含在生成的密码哈希字符串中,因此无需单独生成和存储它们。当用户下次登录时,可以这样验证密码:

if (checkIfDoubleHash(storedHash))
  correctPassword = newSafeHashFunction(oldUnsafeHashFunction(password, oldSalt), storedHash)
else
  correctPassword = newSafeHashFunction(password, storedHash)

➽ 注意函数checkIfDoubleHash() ,这是双重哈希的关键和常见陷阱。如果我们普遍接受newSafeHashFunction(password, storedHash)并且攻击者可以获取旧的备份,或者拥有早期 SQL 注入(inject)的值,他可以直接使用旧的哈希值作为密码。

执行checkIfDoubleHash()可以像检查旧盐一样简单,也可以通过将哈希标记为双哈希来进行 future 的证明。大多数框架已经提供了 password_hash()添加这样一个“标记”的函数,以便他们可以在必要时切换到更新的算法。

$2y$10$nOUIs5kJ7naTuTFkBy1veuK0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
 |
 hash-algorithm-descriptor = 2y = BCrypt

这是 Unix crypt() 经常采用的格式。功能。没有什么可以阻止您使用自己的双散列描述符。当然标记也可以存储在单独的数据库字段中。

关于security - 重新散列使用过时函数散列的现有密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49771801/

相关文章:

security - 安全地运行 docker

没有 SecurityManager 的 Java RMI

Javascript:在循环内生成对象键并将对象数组插入每个对象?

hash - 对 Web 服务的密码加盐的原因

phpseclib - 我可以使用用户名、 key 和密码(不是 key 密码)进行连接吗

java - 检测 Java 中的终端命令错误

security - 针对不同客户的全公司密码方案

java - SOAP 故障 : No trusted certs found

c - Dan Bernstein 的 Djb2 哈希函数 : Why use bitwise operator when we can just multiply by 33?

arrays - 使用数组键进行哈希到哈希的简单哈希