在存储密码之前对密码进行两次哈希比只进行一次哈希更安全还是更不安全?

我说的是这样做:

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

而不是这样:

$hashed_password = hash($plaintext_password);

如果它不太安全,你能提供一个好的解释(或一个链接)吗?

另外,使用哈希函数有区别吗?如果混合使用md5和sha1(例如),而不是重复相同的哈希函数,会有任何区别吗?

注1:当我说“双重哈希”时,我指的是对密码进行两次哈希,以使其更加模糊。我说的不是解决碰撞的技术。

注2:我知道我需要添加一个随机的盐,以真正使它安全。问题是用同一个算法进行两次哈希运算对哈希是有利还是有害。


当前回答

大多数答案都是由没有密码学或安全背景的人回答的。但他们错了。使用一个盐,如果可能的话,每个记录都是唯一的。MD5/SHA/等等太快了,与你想要的相反。PBKDF2和bcrypt较慢(这很好),但可以被asic /FPGA/ gpu击败(现在非常实惠)。因此需要一个内存硬的算法:输入scrypt。

这里是关于盐和速度的一个外行解释(但不是关于内存硬算法)。

其他回答

根据我所读到的,实际上可能建议将密码重新哈希数百或数千次。

其思想是,如果您可以花费更多的时间来编码密码,那么攻击者就需要做更多的工作来进行多次猜测以破解密码。这似乎是重哈希的优势——并不是说它在密码学上更安全,而是它只是需要更长的时间来生成字典攻击。

当然,计算机一直在变得更快,所以这种优势会随着时间的推移而减弱(或者需要您增加迭代)。

只有当我在客户端对密码进行哈希,然后将该哈希(使用不同的盐)保存在服务器上时,双哈希才有意义。

这样,即使有人黑进了服务器(从而忽略了SSL提供的安全),他仍然无法获得清晰的密码。

是的,他将拥有入侵系统所需的数据,但他不能使用这些数据来破坏用户拥有的外部帐户。众所周知,人们几乎在任何事情上都使用相同的密码。

他获得清晰密码的唯一方法是在客户端安装一个keygen——这已经不是你的问题了。

简而言之:

客户端上的第一个散列可以在“服务器泄露”场景中保护您的用户。 如果有人掌握了数据库备份,那么服务器上的第二次哈希可以保护您的系统,这样他就不能使用这些密码连接到您的服务。

是的——它减少了可能匹配字符串的数量。

正如你已经提到的,咸散列更好。

这里有一篇文章:http://websecurity.ro/blog/2007/11/02/md5md5-vs-md5/,试图证明为什么它是等价的,但我不确定逻辑。一方面,他们假设没有软件可以分析md5(md5(文本)),但很明显,生成彩虹表是相当简单的。

我仍然坚持我的答案,md5(md5(文本))类型哈希的数量比md5(文本)哈希的数量少,增加了碰撞的机会(即使仍然是一个不太可能的概率),并减少了搜索空间。

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

除此之外,从密码学的角度来说,实际上没有什么不同。

Although there is a crypto primitive called a "hash chain" -- a technique that allows you to do some cool tricks, like disclosing a signature key after it's been used, without sacrificing the integrity of the system -- given minimal time synchronization, this allows you to cleanly sidestep the problem of initial key distribution. Basically, you precompute a large set of hashes of hashes - h(h(h(h....(h(k))...))) , use the nth value to sign, after a set interval, you send out the key, and sign it using key (n-1). The recepients can now verify that you sent all the previous messages, and no one can fake your signature since the time period for which it is valid has passed.

像Bill建议的那样重新哈希几十万次只是浪费你的cpu。如果你担心别人会破坏128位,可以使用更长的密钥。

是的,重哈希减少了搜索空间,但不,这无关紧要——有效的减少是微不足道的。

重散列增加了强制执行所花费的时间,但只执行两次也是次优的。

您真正想要的是使用PBKDF2对密码进行哈希,这是一种经过验证的使用盐和迭代的安全哈希的方法。看看这个SO回应。

编辑:我几乎忘了-不要使用MD5!!!!使用现代加密哈希,如SHA-2家族(SHA-256, SHA-384和SHA-512)。