在发送给服务器端之前,我应该对密码进行哈希处理吗?


110

我注意到大多数站点都通过HTTPS以纯文本形式将密码发送到服务器。如果我不是将密码的哈希值发送到服务器,那有什么好处吗?会更安全吗?


5
@Jader Dias:我知道您没有问这个,但是如果您对它进行哈希处理并不能再保证其安全性,那么可以通过https发送它。实际上,由于您暴露了盐分,因此可能会使它的安全性降低。另外,(在这里说我的话不对劲),算法的混合可能会导致更多的哈希冲突,并使其更容易被黑客攻击。
Merlyn Morgan-Graham

@梅林的“哈希碰撞”好点!
贾德·迪亚斯

混合算法根本不会增加碰撞概率。这就是哈希函数的重点。给定任何输入熵,返回输出在可能的输出空间中任何位置的可能性均等。
JJ

@JJ“混合算法根本不会增加碰撞概率。” 我真的很想看到这一说法的证明。让我阻止您:这是错误的,通常会增加碰撞。我可以很容易地构造一个哈希函数,使得h(x)不是常数0,而是所有x的h(h(x))= 0。因此,您将必须参考哈希算法的确切集合以及如何将它们混合使用。然后,您需要证明您的陈述。即使对于多个SHA(含盐),AFAIK也是一个未解决的问题。基本上我们相信这是对的。密码学很难。
怪胎

Answers:


155

这是一个老问题,但我感到有必要就这一重要问题发表意见。这里有太多错误信息

OP从未提及过通过HTTP明确发送密码-仅HTTPS,但是出于某种原因,许多人似乎正在响应通过HTTP发送密码的问题。说:

我认为密码绝不应以纯文本形式保留(更不用说传输了)。这意味着不保存在磁盘上,甚至不保存在内存中。

在此做出回应的人们似乎认为HTTPS是灵丹妙药,但事实并非如此。但是,它当然可以极大地帮助您,并且应该在任何经过​​身份验证的会话中使用。

确实不需要知道原始密码是什么。 所需要的只是基于用户选择的原始文本生成(并可靠地重新生成)身份验证“密钥”的可靠方法。在理想的世界中,此文本应立即使用不可逆的盐将其散列,从而生成“密钥”。该盐对于所生成的用户凭证应该是唯一的。此“密钥”将是您的系统用作密码的密钥。这样,如果您的系统将来受到威胁,这些凭据将仅对您自己的组织有用,而在其他地方,用户会变得懒惰并使用相同的密码。

所以我们有一把钥匙。现在,我们需要清除客户端设备上密码的任何痕迹。

接下来,我们需要将该密钥用于您的系统。您绝对不应“明文”传送密钥或密码。甚至没有通过HTTPS。HTTPS是不可渗透的。实际上,许多组织可以成为受信任的MITM,而不是从攻击角度出发,而是对流量进行检查以实施自己的安全策略。这会削弱HTTPS,这并不是它发生的唯一方式(例如,重定向到HTTP MITM攻击)。永远不要认为它是安全的。

为了解决这个问题,我们用一次随机数散列密钥。此随机数对于每次向系统提交密钥都是唯一的-如果需要多次发送,即使在同一会话中使用相同的凭据,也是如此。一旦此随机数进入您自己的系统,您就可以对其进行撤消,以恢复身份验证密钥并验证请求。

此时,在将其永久存储在您自己的系统中之前,我将不可逆地对其进行哈希处理。这样,您可以出于SSO之类的目的与合作伙伴组织共享证书的盐,同时能够证明您自己的组织不能冒充用户。这种方法的最好之处在于,您绝不会在未经用户授权的情况下共享用户产生的任何内容。

做更多的研究,因为它比我已经透露的更多,但是如果您想为用户提供真正的安全性,我认为这种方法是目前最完整的解决方案。

TL; DR:

使用HTTPS。安全且不可逆地对密码进行哈希处理,每个密码使用唯一的盐。在客户端上执行此操作-不要传输其实际密码。将用户原始密码传输到您的服务器永远不会“确定”或“良好”。清除所有原始密码的痕迹。不管HTTP / HTTPS都使用随机数。在许多级别上它都更加安全。(回答OP)。


25
我刚刚检查了gmail和facebook-chrome开发人员工具告诉我这两个POST,都包含一个以纯文本格式(无盐)的用户名和密码的urlencoded消息。大型参与者为何/为何不在客户端上使用随机数加盐?
gremwell

18
您用随机数哈希密钥,并声称能够在服务器端反转随机数。那你是在强行散列吗?或者,当您获得hash = HASH(secret + nonce)时如何检索随机数HASH应该是不可逆的函数。你实现了吗?我认为您的解释不可行。您可以创建协议流程图吗?

19
如果您不信任HTTPS,那么每一个努力都是没有意义的!您的代码本身是通过电线传送的,攻击者可以修改/替换您为保护密码安全
所做的

3
可以重写证书的MitM可以重写随机数。或萨吉德所说的。
leewz

4
如果您担心带有HTTPS的MITM,向客户端发送盐分以使客户端可以在将哈希传输回服务器之前对盐分进行盐分有什么意义?似乎毫无意义。也可以只对服务器进行无盐哈希处理,然后使用盐再次在服务器上进行哈希处理。显然,客户端也不可能是客户端盐的生成器,因为下一次登录将是不同的,并且不会计算相同的哈希服务器端。
暗恋

24

由于它是通过HTTPS传输的,因此无需散列即可发送密码绝对是很好的选择(通过HTTPS传输的不是明文)。此外,如果您的应用程序依靠HTTPS来确保其内容安全,那么在通过HTTPS发送密码之前对密码进行哈希处理是没有用的(即,如果攻击者可以对网络上的数据进行解密,那么无论如何您都会被搞砸)


5
这应该不是问题。如果客户端使用代理,则所有代理将看到的是HTTPS加密数据。如果您正在谈论中间人攻击,则正确配置的证书应该可以防止这种情况。
基尔斯顿·阿诺德

7
@Jader:对数据的摆弄不会阻止MITM攻击,因为它可以中继发生的任何事情。传输密码还是散列都没有关系。那是完全不同的事情。
David Thornley,2010年

2
SSL(HTTPS =基于SSL的HTTP)的目的是阻止MITM。
yfeldblum

1
@carnold-MINTM-重定向到http怎么办?大多数人会注意到吗?sslstrip - securityfocus.com/brief/910
内特Ç

1
@Jader Dias您试图阻止一个不存在的问题。HTTPS可以解决此问题,客户端哈希不会增加任何安全性。客户端永远不会被信任。

17

不,实际上这将是一个漏洞。如果攻击者能够从数据库中获取哈希,那么他可以使用它进行身份验证而无需破解它。用户或攻击者在任何情况下都不能获得哈希密码。

哈希密码的全部目的是增加额外的安全性。如果攻击者能够使用SQL Injection或不安全的备份从数据库中获取哈希和盐,那么他必须通过强行强制查找纯文本。 约翰开膛手John the Ripper)通常用于破解盐腌的密码哈希。

不使用https违反了OWASP Top 10:A9传输层保护不足

编辑: 如果在您的实现中您计算a sha256(client_salt+plain_text_password),然后在服务器端计算另一个哈希,sha256(server_salt+client_hash)则这不是一个严重的漏洞。但是,它仍然易于窃听和重播请求。因此,这仍然明显违反WASP A9。但是,这仍将消息摘要用作安全层。

我所见到的最接近客户端替换https的东西是javascript密钥交换中diffie-hellman。但是,这确实防止了主动的MITM攻击,因此直到技术上都违反了OWASP A9。该代码的作者同意这不是HTTPS的完全替代,但是它总比没有好,而且比客户端哈希系统好。


4
实际上,我会在服务器中再次对其进行哈希处理,因此请考虑此情况编辑您的答案。
Jader Dias

@Rook与diffie-hellman密钥交换一起使用https是“无用的”解决方案吗?(我的意思是我们只能使用https而diffie helman不会增加安全性imao)
Michel Gokan 2012年

@Michel Kogan DH密钥交换可与其他工具一起在HTTP中使用。
rook 2012年

1
@Rook最佳实践是在服务器上应用哈希,因此,我认为您应该更新答案的开头,不要忽略客户端哈希,只有这样,然后再提及服务器的散列​​和盐不能暴露。
LeventePánczél2014年

8

通过导线发送散列完全无法达到散列的目的,因为攻击者可以简单地发送散列而忽略密码。简而言之,一个试图在明文中使用哈希表的系统是开放的,并且可以通过网络嗅探进行妥协。


2
这似乎完全牛逼了……哈希比密码安全性如何?
LeventePánczél2014年

1
这仅适用于“哑”哈希。考虑一下:服务器将盐S发送到客户端,而客户端执行HASH(S + PASSWORD),然后将其发送到服务器。服务器仅针对当前会话接受该特定哈希。攻击者确实可以发送哈希并忘记密码,但仅适用于当前会话。因此,它比纯文本安全。
你好世界

更新:摘要访问身份验证更加复杂:en.wikipedia.org/wiki/Digest_access_authentication
Hello World

2
明确一点:当我说“破坏了哈希的目的”时,我指的是在将密码存储在数据库中之前对哈希密码进行加密的常见且安全的做法。尽管如此,该论点仍然认为,如果没有其他步骤,发送散列值而不是密码不会提高安全性。
Paul Keister 2014年

补充一下保罗所说的话:如果有人想在其他地方阅读更多有关这种攻击的信息,则称为“重播攻击”。

5

纯文本密码永远不会(即使使用HTTPS时)也不会离开客户端。在离开客户端之前,应该不可逆地对其进行哈希处理,因为服务器不需要知道实际的密码。

散列然后传输解决了在多个位置使用相同密码的惰性用户的安全性问题(我知道我愿意)。但这并不能保护您的应用程序,因为黑客可以访问数据库(或以其他任何方式可以访问哈希),因为黑客可以传输哈希并让服务器接受它。

要解决此问题,您当然可以仅对服务器收到的哈希值进行哈希处理,然后将其称为一天。

我要在基于套接字的Web应用程序中解决此问题的方法是,服务器与客户端连接时会生成一个salt(哈希之前要添加的随机字符串)并将其存储在sockets变量中,然后传输此哈希给客户。客户端获取用户密码,对其进行哈希处理,从服务器中添加盐并对整个对象进行哈希处理,然后再将其传输至服务器。然后将其发送到服务器,该服务器将该哈希与哈希(DB + salt中的哈希)进行比较。据我所知,这是一个很好的方法,但是,公平地说,我对该主题的阅读不多,如果对任何事情我都错了,我希望予以纠正:)


3

使用HTTP摘要-即使通过http也可以保护密码(但最好的用法是通过https进行http摘要)

维基百科:

HTTP摘要访问身份验证是Web服务器可以用来与Web用户协商凭据(使用HTTP协议)的公认方法之一。摘要式身份验证旨在取代基本访问身份验证的未加密使用,从而可以安全地建立用户身份,而不必通过网络以明文形式发送密码。摘要式身份验证基本上是MD5加密散列的一种应用,它使用nonce值来防止加密分析。

链接:http//en.wikipedia.org/wiki/Digest_access_authentication

如果要查看“现实生活”的用法,可以查看phpMyID-使用HTTP摘要身份验证的php openid提供程序 http://siege.org/phpmyid.php

..或您可以从http://php.net/manual/zh/features.http-auth.php上的php auth示例开始

HTTP摘要RFC:http//www.faqs.org/rfcs/rfc2617

根据我的测试,所有现代浏览器都支持它...


HTTP Digest实现了我在这个问题中的意思,但是如果我们使用HTTPS Digest(SSL + HTTP Digest),我们会有任何优势吗?
贾德·迪亚斯

一个主要区别是,所有内容都以加密方式发送/接收-HTTP标头发送和接收以及html答复。对于随机尝试使用“中间人攻击”来“破解” ssl的人,http摘要将使他搜索另一个更简单的目标成为额外的动机,或者如果他正在记录所有捕获的流量,则您的密码仍然更安全。我可能误解了这个问题,英语不是我的母语。
vlad b。

散列密码具有一个很大的优势:如果以某种方式记录或捕获了流量,它将使该人的工作更加困难。同样,使用http摘要,如果并非总是需要ssl,则可以让用户在http和https之间进行选择。或者,您可以对不同的服务器使用不同的协议(例如,我不强制执行https查看/修改较少的导入和数据(用户名,头像上传),而是对计费和网站的其他部分强制执行https(那样我可以减少负载)一些服务器(如果需要的话))
vlad b。2010年

3

如果您希望将HTTPS上的明文密码替换为HTTP上的哈希密码,那么您会遇到麻烦。打开通信通道时,HTTPS会生成一个随机的共享事务密钥。这很难破解,因为您几乎仅限于强行强制用于(相对)短期交易的共享密钥。而您的哈希值可以被嗅探,脱机并在彩虹表中查找,或者长时间被强行使用。

但是,通过HTTPS发送的基本客户端密码混淆(不是哈希)确实具有一定的价值。如果我没记错的话,有些银行实际上使用了这种技术。此技术的目的不是保护密码不被电线嗅探。相反,这是为了使密码无法用于笨拙的间谍工具和浏览器插件,而这些工具和浏览器插件仅会捕获他们看到的每个HTTPS GET / POST请求。我看到一个从恶意网站捕获的日志文件,该文件是从用户会话捕获的400MB随机GET / POST事务。您可以想象,仅使用HTTPS的网站将在日志中显示明文密码,但是具有非常基本的混淆(ROT13)的网站也将显示未立即使用的密码。


“但是具有非常基本的混淆(ROT13)的网站也将显示不立即使用的密码” –这与原始陈述相矛盾。关键在于它们不是立即使用,但这确实是徒劳的。密码及其ROT13是等效的。但是,如果您使用SHA2密码,则密码将不会出现在日志中(因此您的管理员不会知道用户可能使用的其他系统密码),并且您几乎不再违反几乎所有的隐私法。
LeventePánczél2014年

2

如果连接到https服务器,则服务器和浏览器之间的数据流应被加密。数据在发送之前和接收之后只是纯文本。维基百科文章


代理不拦截这些数据吗?
贾德·迪亚斯

据我了解,它们确实可以,但是代理不负责加密/解密,除非它是不道德的代理,否则仅传递数据。加密类型和强度取决于服务器和客户端都可以支持的内容。
杰克2010年

1
即使代理是不道德的,它也不能解密数据,因为它是使用服务器的公共密钥加密的。代理解密数据的唯一方法是使用其他密钥来欺骗服务器的证书
Kiersten Arnold 2010年

@贾德 如果这样做的话,这将使HTTPS非常la脚。使用HTTPS对服务器进行身份验证时,您将得到一个保证(假设证书有效),该连接将连接到特定服务器,并且从一端到另一端都有一条加密路径。假设,当然可以使用中间人攻击来欺骗您,但这与基本的Web代理不同。
Peter Recore

2

免责声明:我绝不是安全专家,并且我寄希望于其他人批评我的立场过于谨慎或可取,我将从中学习。话虽如此,我只想强调一下,散列在离开客户端时并不意味着您不必在将其放入数据库之前就在后端进行散列。

两者都做

都这样做是因为:

  1. 搭接过程中的哈希有助于掩盖传输中的漏洞,如果SSL连接遭到破坏,他们仍然看不到原始密码。可以模拟授权用户并不重要,但是它将保护您的用户免遭密码与电子邮件的关联读取。大多数人不遵循最佳做法,并且在许多帐户中使用相同的密码,因此这可能会对您的访问者造成严重漏洞。

  2. 如果有人以某种方式能够从数据库中读取密码(确实发生这种情况,请考虑使用SQL注入),那么他们仍然将无法执行通过我的API冒充用户的特权操作。这是因为哈希不对称;即使他们知道存储在数据库中的哈希,也不会知道用于创建哈希的原始密钥,而这正是您的身份验证中间件用来进行身份验证的内容。这也是为什么您应始终对哈希存储加盐的原因。

当然,如果他们能够自由控制从数据库中读取所需内容,他们可能会造成很多其他损失。

我只想在此强调一下,如果您确实决定在离开客户之前对密钥进行哈希处理,那还不够-后端哈希对imo更为重要,这就是为什么:如果有人正在拦截来自您的流量客户,那么他们将看到该password字段的内容。无论是散列还是纯文本,都没关系-他们可以逐字复制,以模拟授权的客户。(除非您遵循@ user3299591概述的步骤,否则我建议您这样做)。另一方面,散列DB列是必要的,一点也不难实现。



0

散列密码并通过非加密通道发送密码实际上会不太安全。您将在客户端上公开您的哈希算法。黑客可能只是嗅探密码的哈希值,然后在以后使用它进行黑客入侵。

通过使用HTTPS,您可以防止黑客从单一来源获取密码,因为HTTPS使用两个均加密的通道。


1
实际上,我将再次在服务器中对其进行哈希处理,并且无论如何我都将使用HTTPS,因此请编辑考虑此情况的答案。
贾德·迪亚斯

@Jader,重点是,攻击者现在需要的只是第一个哈希,而不是密码。实际上,您现在在客户端对密码进行的哈希运算与密码本身一样有用。因此,您实际上并没有获得太多安全性。
Peter Recore

有没有人想过不发送令牌的一部分?例如,如果您知道哈希的方法,为什么要发送它。服务器不应该知道要解密的客户端密钥吗?
jemiloii

0

是否存在优势,以及它是否更(或更少)安全,实际上取决于实现。可以说存在一些优势,但是如果实施不当,肯定可以创建一种解决方案,该解决方案比通过纯文本密码安全性低。

这可以从两种类型的攻击的角度来看:一种可以访问网络流量,另一种可以访问数据库。

如果您的攻击者可以截获网络流量的纯文本版本,则看到密码的哈希值比看到纯文本的密码更安全。尽管攻击者仍可以使用该哈希登录到您的服务器,但它需要对该哈希进行强力破解(有时是预先计算)才能确定在其他系统上可能有用的密码。人们应该在不同的系统上使用不同的密码,但通常不要这样做。

如果攻击者可能通过备份的副本获得了对数据库的访问权限,那么您将要确保仅凭这一知识就无法登录。例如,如果您存储的登录名为的哈希值杂乱无章hash(login_name+password),并从客户端传递了相同的哈希值以进行直接比较,则攻击者可以随机选择一个用户,发送从数据库读取的哈希值并以该用户不知道密码,从而扩大了违规范围。在这种情况下,以明文形式发送密码会更加安全,因为攻击者需要知道明文才能登录,即使拥有数据库副本也是如此。 这是实现的关键。 无论是发送纯文本密码还是该密码的客户端哈希,都应在服务器端对该值进行哈希处理,并将该哈希值与存储在用户记录中的哈希值进行比较。

要记住的概念:

  • 您可以通过将一些范围唯一的值(通常是行唯一的)混合到哈希中来“加盐”。其目的是即使哈希表示的纯文本值相同,也可以确保彼此唯一的哈希,因此具有相同密码的两个用户仍将具有不同的哈希。不必把盐当作秘密。
  • 进行身份验证时,请始终在服务器端对从客户端作为密码传递的任何值进行哈希处理(即使该值已被哈希化),并将其与存储在数据库中的预先哈希化的值进行比较。这可能需要存储原始密码的双哈希版本。
  • 进行哈希处理时,请考虑在哈希中添加服务器/集群唯一的盐以及行唯一的盐,以防止与查找表中的任何预先计算的哈希值匹配。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.