我注意到大多数站点都通过HTTPS以纯文本形式将密码发送到服务器。如果我不是将密码的哈希值发送到服务器,那有什么好处吗?会更安全吗?
我注意到大多数站点都通过HTTPS以纯文本形式将密码发送到服务器。如果我不是将密码的哈希值发送到服务器,那有什么好处吗?会更安全吗?
Answers:
这是一个老问题,但我感到有必要就这一重要问题发表意见。这里有太多错误信息
OP从未提及过通过HTTP明确发送密码-仅HTTPS,但是出于某种原因,许多人似乎正在响应通过HTTP发送密码的问题。说:
我认为密码绝不应以纯文本形式保留(更不用说传输了)。这意味着不保存在磁盘上,甚至不保存在内存中。
在此做出回应的人们似乎认为HTTPS是灵丹妙药,但事实并非如此。但是,它当然可以极大地帮助您,并且应该在任何经过身份验证的会话中使用。
确实不需要知道原始密码是什么。 所需要的只是基于用户选择的原始文本生成(并可靠地重新生成)身份验证“密钥”的可靠方法。在理想的世界中,此文本应立即使用不可逆的盐将其散列,从而生成“密钥”。该盐对于所生成的用户凭证应该是唯一的。此“密钥”将是您的系统用作密码的密钥。这样,如果您的系统将来受到威胁,这些凭据将仅对您自己的组织有用,而在其他地方,用户会变得懒惰并使用相同的密码。
所以我们有一把钥匙。现在,我们需要清除客户端设备上密码的任何痕迹。
接下来,我们需要将该密钥用于您的系统。您绝对不应“明文”传送密钥或密码。甚至没有通过HTTPS。HTTPS是不可渗透的。实际上,许多组织可以成为受信任的MITM,而不是从攻击角度出发,而是对流量进行检查以实施自己的安全策略。这会削弱HTTPS,这并不是它发生的唯一方式(例如,重定向到HTTP MITM攻击)。永远不要认为它是安全的。
为了解决这个问题,我们用一次随机数散列密钥。此随机数对于每次向系统提交密钥都是唯一的-如果需要多次发送,即使在同一会话中使用相同的凭据,也是如此。一旦此随机数进入您自己的系统,您就可以对其进行撤消,以恢复身份验证密钥并验证请求。
此时,在将其永久存储在您自己的系统中之前,我将不可逆地对其进行哈希处理。这样,您可以出于SSO之类的目的与合作伙伴组织共享证书的盐,同时能够证明您自己的组织不能冒充用户。这种方法的最好之处在于,您绝不会在未经用户授权的情况下共享用户产生的任何内容。
做更多的研究,因为它比我已经透露的更多,但是如果您想为用户提供真正的安全性,我认为这种方法是目前最完整的解决方案。
TL; DR:
使用HTTPS。安全且不可逆地对密码进行哈希处理,每个密码使用唯一的盐。在客户端上执行此操作-不要传输其实际密码。将用户原始密码传输到您的服务器永远不会“确定”或“良好”。清除所有原始密码的痕迹。不管HTTP / HTTPS都使用随机数。在许多级别上它都更加安全。(回答OP)。
由于它是通过HTTPS传输的,因此无需散列即可发送密码绝对是很好的选择(通过HTTPS传输的不是明文)。此外,如果您的应用程序依靠HTTPS来确保其内容安全,那么在通过HTTPS发送密码之前对密码进行哈希处理是没有用的(即,如果攻击者可以对网络上的数据进行解密,那么无论如何您都会被搞砸)
不,实际上这将是一个漏洞。如果攻击者能够从数据库中获取哈希,那么他可以使用它进行身份验证而无需破解它。用户或攻击者在任何情况下都不能获得哈希密码。
哈希密码的全部目的是增加额外的安全性。如果攻击者能够使用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的完全替代,但是它总比没有好,而且比客户端哈希系统好。
通过导线发送散列完全无法达到散列的目的,因为攻击者可以简单地发送散列而忽略密码。简而言之,一个试图在明文中使用哈希表的系统是开放的,并且可以通过网络嗅探进行妥协。
纯文本密码永远不会(即使使用HTTPS时)也不会离开客户端。在离开客户端之前,应该不可逆地对其进行哈希处理,因为服务器不需要知道实际的密码。
散列然后传输解决了在多个位置使用相同密码的惰性用户的安全性问题(我知道我愿意)。但这并不能保护您的应用程序,因为黑客可以访问数据库(或以其他任何方式可以访问哈希),因为黑客可以传输哈希并让服务器接受它。
要解决此问题,您当然可以仅对服务器收到的哈希值进行哈希处理,然后将其称为一天。
我要在基于套接字的Web应用程序中解决此问题的方法是,服务器与客户端连接时会生成一个salt(哈希之前要添加的随机字符串)并将其存储在sockets变量中,然后传输此哈希给客户。客户端获取用户密码,对其进行哈希处理,从服务器中添加盐并对整个对象进行哈希处理,然后再将其传输至服务器。然后将其发送到服务器,该服务器将该哈希与哈希(DB + salt中的哈希)进行比较。据我所知,这是一个很好的方法,但是,公平地说,我对该主题的阅读不多,如果对任何事情我都错了,我希望予以纠正:)
使用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
根据我的测试,所有现代浏览器都支持它...
如果您希望将HTTPS上的明文密码替换为HTTP上的哈希密码,那么您会遇到麻烦。打开通信通道时,HTTPS会生成一个随机的共享事务密钥。这很难破解,因为您几乎仅限于强行强制用于(相对)短期交易的共享密钥。而您的哈希值可以被嗅探,脱机并在彩虹表中查找,或者长时间被强行使用。
但是,通过HTTPS发送的基本客户端密码混淆(不是哈希)确实具有一定的价值。如果我没记错的话,有些银行实际上使用了这种技术。此技术的目的不是保护密码不被电线嗅探。相反,这是为了使密码无法用于笨拙的间谍工具和浏览器插件,而这些工具和浏览器插件仅会捕获他们看到的每个HTTPS GET / POST请求。我看到一个从恶意网站捕获的日志文件,该文件是从用户会话捕获的400MB随机GET / POST事务。您可以想象,仅使用HTTPS的网站将在日志中显示明文密码,但是具有非常基本的混淆(ROT13)的网站也将显示未立即使用的密码。
如果连接到https服务器,则服务器和浏览器之间的数据流应被加密。数据在发送之前和接收之后只是纯文本。维基百科文章
免责声明:我绝不是安全专家,并且我寄希望于其他人批评我的立场过于谨慎或可取,我将从中学习。话虽如此,我只想强调一下,散列在离开客户端时并不意味着您不必在将其放入数据库之前就在后端进行散列。
两者都做
都这样做是因为:
搭接过程中的哈希有助于掩盖传输中的漏洞,如果SSL连接遭到破坏,他们仍然看不到原始密码。可以模拟授权用户并不重要,但是它将保护您的用户免遭密码与电子邮件的关联读取。大多数人不遵循最佳做法,并且在许多帐户中使用相同的密码,因此这可能会对您的访问者造成严重漏洞。
如果有人以某种方式能够从数据库中读取密码(确实发生这种情况,请考虑使用SQL注入),那么他们仍然将无法执行通过我的API冒充用户的特权操作。这是因为哈希不对称;即使他们知道存储在数据库中的哈希,也不会知道用于创建哈希的原始密钥,而这正是您的身份验证中间件用来进行身份验证的内容。这也是为什么您应始终对哈希存储加盐的原因。
当然,如果他们能够自由控制从数据库中读取所需内容,他们可能会造成很多其他损失。
我只想在此强调一下,如果您确实决定在离开客户之前对密钥进行哈希处理,那还不够-后端哈希对imo更为重要,这就是为什么:如果有人正在拦截来自您的流量客户,那么他们将看到该password
字段的内容。无论是散列还是纯文本,都没关系-他们可以逐字复制,以模拟授权的客户。(除非您遵循@ user3299591概述的步骤,否则我建议您这样做)。另一方面,散列DB列是必要的,一点也不难实现。
SSL / TLS不能取代现时吗?我看不到它的附加价值,因为SSL / TLS还可以防止重放攻击。
散列密码并通过非加密通道发送密码实际上会不太安全。您将在客户端上公开您的哈希算法。黑客可能只是嗅探密码的哈希值,然后在以后使用它进行黑客入侵。
通过使用HTTPS,您可以防止黑客从单一来源获取密码,因为HTTPS使用两个均加密的通道。
是否存在优势,以及它是否更(或更少)安全,实际上取决于实现。可以说存在一些优势,但是如果实施不当,肯定可以创建一种解决方案,该解决方案比通过纯文本密码安全性低。
这可以从两种类型的攻击的角度来看:一种可以访问网络流量,另一种可以访问数据库。
如果您的攻击者可以截获网络流量的纯文本版本,则看到密码的哈希值比看到纯文本的密码更安全。尽管攻击者仍可以使用该哈希登录到您的服务器,但它需要对该哈希进行强力破解(有时是预先计算)才能确定在其他系统上可能有用的密码。人们应该在不同的系统上使用不同的密码,但通常不要这样做。
如果攻击者可能通过备份的副本获得了对数据库的访问权限,那么您将要确保仅凭这一知识就无法登录。例如,如果您存储的登录名为的哈希值杂乱无章hash(login_name+password)
,并从客户端传递了相同的哈希值以进行直接比较,则攻击者可以随机选择一个用户,发送从数据库读取的哈希值并以该用户不知道密码,从而扩大了违规范围。在这种情况下,以明文形式发送密码会更加安全,因为攻击者需要知道明文才能登录,即使拥有数据库副本也是如此。 这是实现的关键。 无论是发送纯文本密码还是该密码的客户端哈希,都应在服务器端对该值进行哈希处理,并将该哈希值与存储在用户记录中的哈希值进行比较。
要记住的概念: