将哈希值再次哈希是否能增加安全性?

5

可能是重复的问题:
“双重哈希”比仅哈希一次密码不安全吗?

我正在使用PHP中的sha1加密密码,但我想知道将哈希函数再次应用于哈希值是否比仅对密码进行哈希更加安全。

例如:

$hash = sha1($pwd);

比任何不安全的都要不安全
$hash = sha1(sha1($pwd));

我认为这是没有问题的,因为反向查找网站无法找到哈希值的匹配项。


1
请查看以下链接: https://dev59.com/onRC5IYBdhLWcg3wSu97 - Michael
3
快速的SHA算法在各种场合都很有用,但在密码存储方面并不适用。密码哈希应该使用计算成本高昂的算法,比如PBKDF2。 - lynks
希望这个标记不仅仅是被关闭,而是被转移到加密货币板块。我会在 META 上创建一个讨论。 - Maarten Bodewes
@owlstead 我相信我们在各个地方都有很多重复的内容。在这里,加密.SE和安全.SE上都是如此。我认为迁移在这里没有用处。 - CodesInChaos
@CodesInChaos 嗯,完全正确。在另一个网站上检查重复问题的方法和问题的转移有点不方便,因此即将在 META 上发布帖子。 - Maarten Bodewes
3个回答

2

双重哈希并没有什么用处。盐值则是有用的(链接)


2
为了使您的密码存储更安全,您不应该使用 sha1 或任何其他快速哈希算法,而是应该使用像 BCrypt 这样的“密钥派生函数”。
快速算法的问题在于,您可以使用普通硬件每秒计算 3 十亿个 sha1 哈希值(2012 年)。这使得在不到一毫秒的时间内,可以对大约 500,000 个英语单词的整个字典进行暴力破解!
您示例中的第二个问题是缺少盐。如果您不为每个密码使用唯一的盐,则攻击者可以构建一个单一的彩虹表来获取所有密码。
BCrypt 是专门设计用于哈希密码的,并且因此很“慢”(需要一些计算时间)。通过成本因素,您可以适应未来(因此更快)的硬件所需的时间。在内部,它执行类似于您建议的重复哈希多次的操作,但是以安全的方式进行。
使用BCrypt可以像使用sha1哈希一样简单。PHP 5.5将拥有自己的函数password_hash()password_verify(),以简化此任务。还有一个兼容性包可供下载,适用于PHP 5.3 / 5.4,在password_compat处提供。

-1

首先,虽然sha1本身很弱,但它比明文存储密码要好。任何加密、哈希或其他混淆方式都比明文更安全!

sha1的问题在于它速度很快,因此生成哈希值以进行破解也很快。加盐可以很好地解决这个问题,但如果您的服务器被攻击并且您的盐哈希值存储在某个字符串中,那么这个优势就不存在了...

如果您不想使用mcrypt或其他加密方法,可以像这样稍微混淆一下您的sha1哈希值:

$my_super_sha1_hash = 
sha1(
    sha1(
        substr(
            sha1($username)
            , 0
            , strlen($password) 
        )
    )
    .sha1(
        substr(
            sha1($password)
            , 0
            , 40-strlen($password)
        )
    )
);

通过混合用户名和密码,并使用(未知)密码的长度来确定在哈希后使用哪些位于字符串中,每个盐都是独特的但不是随机的,因此结果在所有用户之间是一致的,而且更难破解,因为必须考虑密码和用户名的字符串长度。

这比仅对用户名和密码串联进行哈希处理要不够安全 - Lie Ryan
你没有理解盐的作用。它不是秘密,而是为了阻止多目标攻击而对每个哈希块使用不同的盐值。即使攻击者知道盐的值,仍然有益处。(尽管除了每个用户唯一值之外,使用未知值也是额外的优势)。你还忘记提到关键强化,即使用对攻击者计算昂贵的哈希函数。 - CodesInChaos
你的混合方案也很愚蠢。对于短密码,盐空间变得非常小;对于长密码,密码的贡献消失了;对于非常长的密码,代码甚至无法正常工作。你的方案明显不如简单的 sha1(sha1(username).sha1(password)) 或者只是 sha1(username."|".password) - CodesInChaos
这篇文章的意思并不是说“这里有一个超级安全的函数,使用它就可以了”,而是关于单独使用sha1太弱了,任何自制的sha1哈希解决方案都需要大大增加复杂性。在我看来,这样的函数比将随机生成的盐值与哈希值一起存储具有优势,因为如果数据库用户表被盗,盐值仍然未知,并且对攻击者关于计算方法的提示毫无帮助,同时仍然为每个密码提供唯一的盐值。 - WebChemist
1
我不明白为什么这比简单地将用户名和密码连接起来不安全。如果窃取的数据库哈希值被反转并且他们看到了80个字符的双sha1连接字符串,那么完整用户名或密码的直接sha1子字符串将比部分用户|密码哈希的哈希更加明显。如果php散列代码被攻击者入侵,那么所有这些都是无意义的,因为攻击者可以运行散列函数,在这种情况下,它至少比您建议的简单连接要更具计算成本。 - WebChemist

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