“双重哈希”比仅哈希一次密码更不安全吗?

324

将密码在存储前进行两次哈希,与仅进行一次哈希相比,哪种更安全?

我所说的是这样做:

$hashed_password = hash(hash($plaintext_password));

而不仅仅是这样:

$hashed_password = hash($plaintext_password);

如果安全性较低,你能提供一个好的解释(或链接)吗?
另外,使用的哈希函数是否有所不同?如果混合使用md5和sha1(例如),而不是重复相同的哈希函数,是否会有所不同?
注意1:当我说“双重哈希”时,我指的是尝试两次哈希密码以使其更加模糊。我不是在谈论解决冲突的技术
注意2:我知道我需要添加一个随机盐来确保安全。问题是使用相同算法两次哈希是否有帮助还是有害。

3
Hash(password)Hash(Hash(password))同样不安全。两者都缺乏语义安全性的概念,即输出不足以与随机数据区分开来。例如,MD5("password")的结果是5f4dcc3b5aa765d61d8327deb882cf99。我知道这是password的MD5哈希值,并且可以从随机值中区分出来。相反,您应该使用HMAC。它具有可证明的安全性并且是一个PRF。 - jww
16个回答

2
双重哈希只有在我在客户端上对密码进行哈希,然后保存该哈希的哈希(使用不同的盐)才有意义。
这样即使有人黑入服务器(无视SSL提供的安全性),他仍然无法获得明文密码。
是的,他将拥有进入系统所需的数据,但他将无法使用该数据来危及用户的外部帐户。而人们众所周知地几乎为任何事情使用相同的密码。
他能够访问明文密码的唯一方法是在客户端上安装keygen - 这已经不再是您的问题了。
因此简而言之:
1. 在客户端上的第一次哈希可在“服务器遭到黑客攻击”的情况下保护您的用户。 2. 服务器上的第二次哈希用于保护您的系统,如果有人获得了您的数据库备份,他将无法使用这些密码连接到您的服务。

1
+1 我一直在等待像这样的答案,因为我想到了同样的情况,即您不想在客户端存储明文密码,但也不想将最终加密的密码发送到网络上进行简单的与数据库比较。 - Mark
3
如果你的服务器被攻击,那么对于 Web 应用程序是没有帮助的。因为你的服务器发送给客户端的代码也会受到攻击。攻击者会禁用你客户端的哈希功能并捕获原始密码。 - Clement Cherlin

0

关于减少搜索空间的担忧在数学上是正确的,尽管搜索空间仍然足够大,对于所有实际目的(假设您使用盐),在2^128。然而,由于我们谈论的是密码,可能的16个字符字符串(字母数字,大小写敏感,加入了一些符号)的数量大约是2^98,根据我草稿纸上的计算。因此,搜索空间的感知减少实际上并不相关。

除此之外,在密码学上实际上没有区别。

虽然有一个名为“哈希链”的密码原语——一种允许您执行一些很酷的技巧的技术,例如在使用签名密钥后披露它,而不会牺牲系统的完整性——在最小时间同步的情况下,这使您可以干净地绕过初始密钥分发的问题。基本上,您预先计算一组大量的哈希值 - h(h(h(h....(h(k))...))),使用第n个值进行签名,在一定时间间隔后,发送密钥,并使用密钥(n-1)进行签名。接收者现在可以验证您发送了所有以前的消息,而且没有人可以伪造您的签名,因为其有效期已过。

重新哈希数十万次就像Bill建议的那样,只是浪费你的CPU...如果你担心人们破解128位,那么使用更长的密钥。

1
重新散列确切地就是要减慢哈希速度。这是基于密码的加密中的一个关键安全功能。请参见PCKS5和PBKDF2的链接。 - orip

0
正如本文中的几个回答所建议的那样,有些情况下可能会提高安全性,而其他情况则肯定会降低安全性。有一个更好的解决方案可以明显提高安全性。不要将哈希计算的次数加倍,而是将您的盐加倍,或者将哈希使用的位数加倍,或两者兼而有之!不要使用SHA-245,而升级到SHA-512。

这并没有回答问题。 - Bill the Lizard
1
双重哈希不值得花费精力,但是增加哈希表的大小是值得的。我认为这是一个更有价值的观点。 - Stefan Rusek

-1

是的。

绝对不要使用传统哈希函数的多次迭代,比如md5(md5(md5(password)))。最好的情况下,你只会获得微小的安全性提升(这样的方案几乎没有任何防御GPU攻击的保护; 只需进行管道处理即可)。在最坏的情况下,每增加一次迭代,你就会减少哈希空间(因此减少了安全性)。在安全方面,明智的做法是假设最坏的情况。

使用由有能力的密码学家设计为有效密码哈希且能够抵御暴力和时间空间攻击的密码哈希函数,包括bcrypt、scrypt,以及在某些情况下PBKDF2。glibc基于SHA-256的哈希函数也是可以接受的。


-1

我要冒昧地说,在某些情况下,它可能更安全...但不要马上给我点踩!

从数学/密码学的角度来看,它不太安全,我相信其他人会给你一个比我更清晰的解释。

然而,存在大型MD5哈希数据库,其中更有可能包含“密码”文本,而不是其MD5哈希值。因此,通过双重哈希,您可以降低这些数据库的有效性。

当然,如果您使用盐,则这种优势(劣势?)就消失了。


-1

双重哈希是丑陋的,因为攻击者很可能已经建立了一个表来生成大多数哈希值。更好的方法是对哈希值进行盐处理,并将哈希值混合在一起。还有一些新的方案可以“签名”哈希值(基本上是盐处理),但以更安全的方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接