当前对该问题的最高投票者指出:
另一个不是安全问题的问题,尽管它与安全相关,但完全无法理解散列密码和加密密码之间的区别。最常见于程序员试图提供不安全的“提醒我的密码”功能的代码中。
这个区别到底是什么?我一直认为散列是一种加密形式。张贴者所指的不安全功能是什么?
当前对该问题的最高投票者指出:
另一个不是安全问题的问题,尽管它与安全相关,但完全无法理解散列密码和加密密码之间的区别。最常见于程序员试图提供不安全的“提醒我的密码”功能的代码中。
这个区别到底是什么?我一直认为散列是一种加密形式。张贴者所指的不安全功能是什么?
散列是一种单向函数(嗯,映射)。这是不可逆的,您应用了安全哈希算法,您无法取回原始字符串。您最多可以做的是生成所谓的“冲突”,即找到提供相同哈希的不同字符串。密码安全散列算法旨在防止发生冲突。您可以通过使用彩虹表来攻击安全哈希,您可以通过在存储之前对哈希应用盐来抵消它。
加密是一种适当的(两种方式)功能。它是可逆的,如果您有密钥,您可以解密损坏的字符串以获得原始字符串。
它所指的不安全功能是,如果您对密码进行加密,您的应用程序会将密钥存储在某处,并且可以访问您的数据库(和/或代码)的攻击者可以通过获取密钥和加密文本来获取原始密码,而使用哈希是不可能的。
人们通常说,如果破解者拥有您的数据库或您的代码,他就不需要密码,因此差别不大。这是幼稚的,因为您仍然有责任保护用户的密码,主要是因为他们中的大多数人确实一遍又一遍地使用相同的密码,从而使他们因泄露密码而面临更大的风险。
散列是一种单向函数,这意味着一旦对密码进行散列,就很难从散列中取回原始密码。加密是一种双向功能,从加密文本中获取原始文本要容易得多。
使用字典攻击很容易击败普通散列,攻击者只需对字典中的每个单词(或达到一定长度的每个字符组合)进行预散列,然后使用这个新字典查找散列密码。为存储的每个散列密码使用唯一的随机盐会使攻击者更难使用此方法。他们基本上需要为您使用的每个盐值创建一个新的唯一字典,从而大大减慢他们的攻击速度。
使用加密算法存储密码是不安全的,因为如果用户或管理员更容易从加密文本中获取原始密码,那么攻击者也更容易这样做。
如上图所示,如果密码被加密,它总是一个隐藏的秘密,有人可以从中提取明文密码。但是,当密码被散列时,您会很放松,因为几乎没有任何方法可以从散列值中恢复密码。
从加密密码和散列密码中提取- 哪个更好?
纯文本密码可以使用对称加密算法(如 DES、AES)或任何其他算法进行加密,并存储在数据库中。在身份验证时(通过用户名和密码确认身份),应用程序将解密存储在数据库中的加密密码,并与用户提供的密码进行比较是否相等。在这种类型的密码处理方法中,即使有人可以访问数据库表,密码也不会简单地重复使用。然而,这种方法也有一个坏消息。如果有人以某种方式获得了加密算法以及您的应用程序使用的密钥,他/她将能够通过解密查看存储在您的数据库中的所有用户密码。“这是我得到的最佳选择”,软件开发人员可能会尖叫,但有没有更好的方法?
是的,有可能是你错过了这里的重点。您是否注意到不需要解密和比较?如果有一种单向转换方法,可以将密码转换为某个转换字,但反向操作(从转换字生成密码)是不可能的。现在,即使有人可以访问数据库,也无法使用转换后的单词来复制或提取密码。在这种方法中,几乎不会有人知道您的用户的绝密密码;这将保护在多个应用程序中使用相同密码的用户。这种方法可以使用哪些算法?
我一直认为加密可以双向转换,最终值可以将您带到原始值,而使用散列,您将无法从最终结果恢复到原始值。
散列算法本质上通常是加密的,但主要区别在于加密通过解密是可逆的,而散列不是。
加密函数通常接受输入并产生相同或稍大大小的加密输出。
散列函数接受输入并产生通常较小的输出,通常也是固定大小的。
虽然不可能获取散列结果并对其“去散列”以取回原始输入,但您通常可以暴力破解产生相同散列的东西。
换句话说,如果身份验证方案采用密码,对其进行哈希处理,并将其与所需密码的哈希版本进行比较,则可能不需要您实际知道原始密码,只知道其哈希值,并且您可以暴力破解即使密码不同,您也可以找到匹配的东西。
通常创建散列函数是为了最大限度地减少冲突的机会,并使仅计算会产生与其他事物相同散列的事物变得困难。
哈希:
它是一种单向算法,一旦散列就不能回滚,这是它对抗加密的最佳点。
加密
如果我们执行加密,将有一个密钥来执行此操作。如果此密钥泄露,您的所有密码都可以轻松解密。
另一方面,即使您的数据库被黑客入侵,或者您的服务器管理员从数据库中获取数据并且您使用了散列密码,黑客也无法破解这些散列密码。如果我们使用带有适当盐的散列和 PBKDF2 的额外安全性,这实际上是不可能的。
如果你想看看你应该如何编写你的哈希函数,你可以访问这里。
有许多算法可以执行散列。
MD5 - 使用消息摘要算法 5 (MD5) 散列函数。输出哈希的长度为 128 位。MD5 算法是由 Ron Rivest 在 1990 年代初设计的,现在不是首选方案。
SHA1 - 使用 1995 年发布的安全散列算法 (SHA1) 散列。输出散列长度为 160 位。尽管使用最广泛,但这并不是今天的首选。
HMACSHA256、HMACSHA384、HMACSHA512 - 使用 SHA-2 系列的函数 SHA-256、SHA-384 和 SHA-512。SHA-2 于 2001 年发布。如哈希函数名称所示,输出哈希长度分别为 256、384 和 512 位。
理想情况下,您应该两者都做。
首先散列通行证密码以实现单向安全性。使用盐以增加安全性。
如果您的密码哈希数据库遭到破坏,然后加密哈希以防御字典攻击。
与其他答案一样正确,在引用所在的上下文中,散列是一种可用于保护信息的工具,加密是一个获取信息的过程,使未经授权的人很难阅读/使用。
这是您可能想要使用其中一个而不是另一个的原因之一 - 密码检索。
如果您只存储用户密码的哈希值,则无法提供“忘记密码”功能。