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

我说的是这样做:

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

而不是这样:

$hashed_password = hash($plaintext_password);

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

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

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

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


当前回答

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

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

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

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

其他回答

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

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

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

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

一般来说,它不会为双重哈希或双重加密提供额外的安全性。如果你能分解一次散列,你就能再分解一次。不过,这样做通常不会损害安全性。

在使用MD5的例子中,您可能知道有一些碰撞问题。“双重哈希”并不能真正帮助防止这种情况,因为相同的碰撞仍然会导致相同的第一个哈希,然后您可以再次MD5以获得第二个哈希。

这确实可以防止字典攻击,比如那些“反向md5数据库”,但盐也是如此。

在切线上,双重加密某些东西并不能提供任何额外的安全性,因为它所做的只是导致一个不同的密钥,这是实际使用的两个密钥的组合。因此寻找“钥匙”的工作不会加倍,因为实际上不需要找到两把钥匙。这对于哈希并不适用,因为哈希的结果通常与原始输入的长度不同。

让我们假设您使用哈希算法:计算rot13,取前10个字符。如果你这样做两次(甚至2000次),就有可能得到一个更快的函数,但结果是相同的(即只取前10个字符)。

同样,也可以创建一个速度更快的函数,其输出与重复哈希函数相同。因此,您对哈希函数的选择非常重要:与rot13示例一样,并没有给出重复哈希将提高安全性。如果没有研究表明该算法是为递归使用而设计的,那么假设它不会为您提供额外的保护是更安全的。

也就是说:对于除了最简单的哈希函数之外的所有函数,很可能需要密码学专家来计算更快的函数,所以如果你正在防范无法访问密码学专家的攻击者,在实践中使用重复哈希函数可能更安全。

Yes.

绝对不要使用传统哈希函数的多次迭代,比如md5(md5(md5(password)))。在最好的情况下,您将获得安全方面的边际增加(这样的方案几乎不能对GPU攻击提供任何保护;直接把它输送出来。)在最坏的情况下,每次添加迭代都会减少哈希空间(从而减少安全性)。在安全性方面,明智的做法是做最坏的打算。

请使用由合格的密码学家设计的密码,该密码是有效的密码哈希,并能抵抗暴力破解和时空攻击。其中包括bcrypt、scrypt,在某些情况下还包括PBKDF2。基于glibc sha -256的散列也是可以接受的。

我要大胆地说,在某些情况下,它更安全……不过先别给我投反对票!

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

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

当然,如果你使用盐,那么这个优点(缺点?)就消失了。