散列密码和加密密码之间的区别

Posted

技术标签:

【中文标题】散列密码和加密密码之间的区别【英文标题】:Difference between Hashing a Password and Encrypting it 【发布时间】:2010-09-24 12:16:13 【问题描述】:

当前票数最高的this question 状态:

另一个与安全问题无关的问题,尽管它与安全相关,但完全无法理解。最常见于程序员试图提供不安全的“提醒我的密码”功能的代码中。

这个区别到底是什么?我一直认为散列是一种加密形式。发帖者所指的不安全功能是什么?

【问题讨论】:

一篇写得很好的文章,介绍了为什么您不应该简单地散列您的秘密/密码。而是使用 HMAC。 benlog.com/articles/2008/06/19/dont-hash-secrets StackExchange 安全博客主题的精彩总结:security.blogoverflow.com/2011/11/… @JayKumar:您链接的文章非常具有误导性。它将密码盐(预计对攻击者可见)与 MAC 密钥(预计将保密)混为一谈。 David J. Liszewski 的链接提供了更准确的描述。 【参考方案1】:

散列是一种单向函数(好吧,一个映射)。这是不可逆的,您应用了安全哈希算法,您无法取回原始字符串。您最多可以做的是生成所谓的“冲突”,即找到提供相同哈希的不同字符串。密码安全散列算法旨在防止发生冲突。您可以通过使用rainbow table 来攻击安全哈希,您可以通过在存储之前将salt 应用于哈希来抵消它。

加密是一种适当的(双向)功能。它是可逆的,如果您有密钥,您可以解密损坏的字符串以获得原始字符串。

它所指的不安全功能是,如果您对密码进行加密,您的应用程序会将密钥存储在某处,并且可以访问您的数据库(和/或代码)的攻击者可以通过获取密钥和加密的文本,而使用哈希是不可能的。

人们通常说,如果破解者拥有您的数据库或您的代码,他就不需要密码,因此差别不大。这是幼稚的,因为您仍然有责任保护用户的密码,主要是因为他们中的大多数确实会一遍又一遍地使用相同的密码,从而使他们因密码泄露而面临更大的风险。

【讨论】:

明确地说,通过散列获得所需的安全性,它必须是具有特定属性的加密安全散列算法,不仅散列是不可逆的,而且在计算上生成任何其他字符串也是不切实际的生成相同的哈希。 是与否...为了您自己的应用程序的安全性,哈希冲突需要难以生成,但不可逆性足以避免密码泄露。 silky:你将如何从糟糕的哈希函数中取回原始密码?我建议你重读 Dave 的评论 如果有的话,有大量冲突的哈希函数对密码的安全性更好,但这显然意味着可以使用更多的密码来登录帐户。 @n00b 盐不能硬编码,因为每个散列项都应该使用单独的盐。加盐的要点是,如果用户A 和用户B 都使用密码“1234”,如果您发现用户A 的密码,您就不能告诉用户B 使用相同的密码,因为他们有不同的加盐。将盐保密并不是安全关键,大多数实现只是将盐连接到表示哈希的二进制 blob 的前面或后面。【参考方案2】:

哈希是一种单向函数,这意味着一旦您对密码进行哈希处理,非常很难从哈希中取回原始密码。加密是一个双向功能,从加密文本中获取原始文本要容易得多。

使用字典攻击可以轻松击败普通哈希,攻击者只需对字典中的每个单词(或达到一定长度的每个字符组合)进行预哈希,然后使用这个新字典查找哈希密码。为存储的每个散列密码使用唯一的随机盐会使攻击者更难使用此方法。他们基本上需要为您使用的每个盐值创建一个新的唯一字典,从而大大减慢他们的攻击速度。

使用加密算法存储密码是不安全的,因为如果用户或管理员更容易从加密文本中取回原始密码,那么攻击者也更容易这样做。

【讨论】:

【参考方案3】:

如上图所示,如果密码被加密,它始终是一个隐藏的秘密,有人可以从中提取明文密码。但是,当密码被散列时,您会很放松,因为几乎没有任何方法可以从散列值中恢复密码。


摘自Encrypted vs Hashed Passwords - Which is better?

加密好不好?

可以使用对称加密算法(如 DES、AES 或任何其他算法)对纯文本密码进行加密,并存储在数据库中。在认证时(用用户名和密码确认身份),应用程序将解密存储在数据库中的加密密码,并与用户提供的密码进行比较是否相等。在这种类型的密码处理方法中,即使有人可以访问数据库表,密码也不会简单地重复使用。然而,这种方法也有一个坏消息。如果有人以某种方式获得了加密算法以及您的应用程序使用的密钥,他/她将能够通过解密查看存储在您的数据库中的所有用户密码。 “这是我得到的最佳选择”,软件开发人员可能会尖叫,但有没有更好的方法?

加密哈希函数(单向)

是的,可能是你错过了这里的重点。您是否注意到不需要解密和比较?如果有一种单向转换方法,可以将密码转换为某个转换字,但反向操作(从转换字生成密码)是不可能的。现在,即使有人可以访问数据库,也无法使用转换后的单词来复制或提取密码。在这种方法中,几乎不会有人知道您的用户的绝密密码;这将保护在多个应用程序中使用相同密码的用户。这种方法可以使用哪些算法?

【讨论】:

好的,但是当您登录服务时,您的密码以明文/加密形式发送,因为如果它作为哈希发送到服务器进行比较。黑客如果知道哈希,就可以将哈希发送到服务器进行登录。这就是为什么需要将用于比较的密码加密发送到服务器,在那里它们被解密和散列。这是安全的吧?只要密码永远不会以未散列的形式长期存储,并且所有出现的加密/明文密码都在不再需要时从任何内存中删除?【参考方案4】:

我一直认为加密可以两种方式进行转换,最终值可以将您带到原始值,而使用散列,您将无法从最终结果恢复到原始值。

【讨论】:

【参考方案5】:

散列算法在本质上通常是加密的,但主要区别在于加密通过解密是可逆的,而散列不是。

加密函数通常接受输入并产生相同或稍大的加密输出。

散列函数接受输入并产生通常较小的输出,通常也是固定大小。

虽然不可能获取散列结果并对其“去散列”以取回原始输入,但您通常可以暴力破解产生相同散列的结果。

换句话说,如果身份验证方案采用密码,对其进行哈希处理,并将其与所需密码的哈希版本进行比较,则可能不需要您实际知道原始密码,只知道其哈希值,并且您可以暴力破解你的方式去匹配的东西,即使它是一个不同的密码。

散列函数的创建通常是为了最大限度地减少冲突的机会,并使仅计算会产生与其他事物相同的散列的事物变得困难。

【讨论】:

【参考方案6】:

散列

这是一种单向算法,一旦散列就不能回滚,这是它对抗加密的最佳点。

加密

如果我们执行加密,将有一个密钥来执行此操作。如果此密钥泄露,您的所有密码都可以轻松解密。

另一方面,即使您的数据库被黑客入侵,或者您的服务器管理员从数据库中获取数据并且您使用了散列密码,黑客也无法破解这些散列密码。如果我们使用带有适当盐的散列和 PBKDF2 的额外安全性,这实际上是不可能的。

如果您想了解如何编写哈希函数,可以访问here。

有许多算法可以执行散列。

    MD5 - 使用消息摘要算法 5 (MD5) 哈希函数。输出哈希的长度为 128 位。 MD5 算法是由 Ron Rivest 在 1990 年代初设计的,现在不是首选。

    SHA1 - 使用 1995 年发布的安全散列算法 (SHA1) 散列。输出散列的长度为 160 位。尽管使用最广泛,但这并不是今天的首选。

    HMACSHA256HMACSHA384HMACSHA512 - 使用函数 SHA-256、SHA-384 和 SHA-512 SHA-2 系列。 SHA-2 于 2001 年发布。如哈希函数名称所示,输出哈希长度分别为 256、384 和 512 位。

【讨论】:

【参考方案7】:

理想情况下,你应该两者都做。

首先散列密码以实现单向安全性。使用盐以提高安全性。

如果您的密码哈希数据库遭到破坏,则对哈希进行加密以防御字典攻击。

【讨论】:

用什么加密?如果他们用你的所有用户密码(散列、加密或其他方式)进入数据库,那么他们就不能找到解密它们的密钥吗? 这不应该被否决。不应该轻易排除这种可能性,即数据库受到损害而应用程序没有受到损害。因此,加密哈希是额外的安全层。 @Luc 我不同意你,我以前的自己。我见过太多没有破坏应用程序代码(或配置文件)的 SQL 注入,我现在认为添加一个秘密是有帮助的,无论是加密形式还是以辣椒的形式,但它不能替换散列。如需更完整的答案,请参阅此处:security.stackexchange.com/a/31846/10863【参考方案8】:

与其他答案一样正确,在引用所在的上下文中,散列是一种可用于保护信息的工具,加密是一个获取信息并使未经授权的人很难阅读的过程/使用。

【讨论】:

【参考方案9】:

这是您可能希望使用其中一个而不是另一个的原因之一 - 密码检索。

如果您只存储用户密码的哈希值,则无法提供“忘记密码”功能。

【讨论】:

您显然没有很好地阅读接受的答案。仔细阅读:您应该提供密码检索功能。您应该提供密码重置功能。多年来,我管理过许多网站,包括 vBulletin、phpBB、e107、IPB、blogspot,甚至是我自己定制的 CMS。作为管理员,您永远不需要拥有某人的预哈希密码。你只是不这样做。你也不应该拥有它。如果你不同意我说的话,让我向你保证:你错了。 抱歉我太生气了。我只是看到太多网站以纯文本形式存储密码,这让我很沮丧。附带说明:一些注重安全的网站喜欢让用户定期更改密码。他们希望确保此人不会将其密码从“Password1”更改为“Password2”。因此他们保留了纯文本密码,以便以后进行这些比较。这不是好的做法。在这种情况下,他们需要做的是首先对密码进行分析,制作一堆相似的密码——对每个密码进行哈希处理——并且只存储 哈希 没问题,它让我回去重新阅读问题并进行进一步研究,所以一切都没有丢失:-)我不确定我在写那个答案时在想什么.欢呼

以上是关于散列密码和加密密码之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

加密方式区别

7.springsecurity密码加密问题

你为啥要在数据库中存储纯文本或加密(非散列)密码?

php密码加密(密码散列)

客户端密码加密[重复]

散列或加密或两者都存储用户的密码? C# Winforms [关闭]