在将密码发送到服务器端之前,我应该散列密码吗?

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

这是一个古老的问题,但我觉得有必要就这件重要的事情提供我的意见。 这里有太多的错误信息

OP从来没有提到通过HTTP发送密码 – 只有HTTPS,但很多人似乎是响应由于某种原因通过HTTP发送密码的问题。 那就是说:

我相信密码永远不应该被保留(更不用说传输)在纯文本。 这意味着不能保存在磁盘上,甚至在内存中。

在这里回应的人们似乎认为HTTPS是一颗银弹,事实并非如此。 然而,这当然有很大的帮助,应该在任何authentication的会话中使用。

真的不需要知道原始密码是什么。 所有这一切都是基于用户select的原始文本生成(并可靠地重新生成)authentication“密钥”的可靠方法。 在一个理想的世界里,这个文本应该立即通过使用不可逆的盐对它进行哈希来产生一个“关键”。 这个salt对于生成的用户凭证应该是唯一的。 这个“钥匙”将是你的系统用作密码的。 这样,如果您的系统将来遭受攻击,那么这些凭据将只对您自己的组织有用,而在其他地方用户已经懒惰并使用相同的密码。

所以我们有一个关键。 现在我们需要清理客户端设备上的任何密码。

接下来,我们需要把这个关键到你的系统。 您不应该“清楚地”传输密钥或密码。 甚至没有通过HTTPS。 HTTPS不是不可阻挡的。 实际上,许多组织可以成为一个可信的MITM,而不是从攻击的angular度来看,而是对stream量进行检查来实施自己的安全策略。 这削弱了HTTPS,并不是它发生的唯一方式(例如redirect到HTTP MITM攻击)。 永远不要认为它是安全的。

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

在这一点上,我将永久存储在你自己的系统中,最后一次散列。 通过这种方式,您可以与SSO等伙伴组织共享凭证,同时能够certificate您自己的组织不能冒充用户。 这种方法的最好的部分是你永远不会分享用户没有他们的授权产生的任何东西。

做更多的研究,因为它甚至比我泄露的更多,但是如果你想为你的用户提供真正的安全,我认为这种方法是目前最完整的答案。

TL; DR:

使用HTTPS。 安全地哈希密码,不可逆转,每个密码独特的盐。 在客户端执行此操作 – 不要传输其实际的密码。 将用户原始密码传输到您的服务器永远不会“正常”或“良好”。 清理原始密码的任何痕迹。 不pipeHTTP / HTTPS使用一个随机数。 在许多层面上它更安全。 (对OP的答复)

由于它是通过HTTPS,绝对没有散列发送密码(通过HTTPS它不是明文)。 而且,如果您的应用程序依赖于HTTPS来保持其内容安全,那么在通过HTTPS发送密码之前散列密码是没有用处的(例如,如果攻击者可以解密线路上的数据,则无论如何都会被拧紧)

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

散列密码的重点是增加一层额外的安全性。 如果攻击者能够使用SQL Injection或不安全的备份从数据库中获取哈希和盐,那么他必须通过暴力破解来find纯文本。 约翰开膛手通常用来打破盐渍密码哈希。

不使用https是违反了OWASP Top 10: A9-传输层保护不足的情况

编辑:如果在你的实现中,你计算一个sha256(client_salt+plain_text_password) ,然后计算服务器端sha256(server_salt+client_hash) sha256(client_salt+plain_text_password)上的另一个散列,那么这不是一个严重的漏洞。 但是,它仍然容易被窃听和重播请求。 因此,这仍然明显违反了WASP A9。 但是,这仍然是利用消息摘要作为安全层。

我所看到的最接近于https的客户端替代品是javascript中密钥交换的diffie-hellman 。 但是,这确实可以防止主动的MITM攻击,因此直到技术性违反OWASP A9。 代码的作者认为,这不是HTTPS的完全替代,然而它比没有客户端散列系统更好。

通过发送一个散列完全破坏散列的目的,因为攻击者可以简单地发送散列并忘记密码。 简而言之,以明文forms使用哈希进行validation的系统是开放的,只能通过networking嗅探进行妥协。

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

维基百科:

HTTP摘要访问身份validation是Web服务器可以用来与Web用户协商凭据(使用HTTP协议)的商定方法之一。 摘要式身份validation旨在取代基本访问身份validation的未encryption使用,允许安全地build立用户身份,而不必通过networking以明文forms发送密码。 摘要式身份validation基本上是应用MD5密码散列,并使用nonce值来防止密码分析。

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

如果你想看到“真实生活”的使用,你可以看看phpMyID – 一个php openid提供者,使用http摘要authenticationhttp://siege.org/phpmyid.php

..或者你可以从PHP身份validation示例http://php.net/manual/en/features.http-auth.php

http消化rfc: http : //www.faqs.org/rfcs/rfc2617

从我的testing中,所有的现代浏览器都支持它。

如果您打算通过HTTPSreplace明码密码,并通过HTTP使用散列密码,那么您就会遇到麻烦。 打开通信通道时,HTTPS将生成一个随机的共享事务密钥。 这很难破解,因为你几乎不能强制用于(相对)短期交易的共享密钥。 而你的散列可以只是嗅,离线,在彩虹表中抬头或只是长时间的强暴。

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

明文显示的密码永远不会(即使使用HTTPS也不会)离开客户端。 离开客户端之前应该进行不可逆转的散列,因为服务器不需要知道实际的密码。

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

为了解决这个问题,你当然可以把服务器收到的哈希哈希,并把它称为一天。

我创build一个基于套接字的Web应用程序中的问题的方法是连接到客户端服务器生成一个盐(随机string添加之前添加),并将其存储在套接字variables,然后它发送这个哈希给客户。 客户端将用户密码,哈希值,从服务器添加盐并整个哈希,然后传输到服务器。 然后将其发送到服务器,将该散列与散列(在数据库+盐中的散列)进行比较。 据我所知,这是一个很好的方法,但是为了公平,我没有在这个主题上读过很多东西,如果我错了我想要纠正的任何东西:)

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

散列密码并通过非encryption通道发送实际上不太安全。 你将在客户端公开你的哈希algorithm。 黑客只能嗅探密码的散列,然后用它来破解。

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

SSL / TLS不是取代现时? 由于SSL / TLS也可以防止重放攻击,所以我没有看到这个附加值。

参考。 https://en.wikipedia.org/wiki/Cryptographic_nonce

免责声明:我不是一个安全专家 – 我发布希望其他人会批评我的立场过于谨慎或可改进,我会从中吸取教训。 有了这个说法,我只想强调一下,当它离开你的客户端时,散列并不意味着在把它放入数据库之前,你不必在后端散列。

做两个

这样做是因为:

  1. 在旅途中散步有助于覆盖传输的漏洞,如果SSL连接受到威胁,他们仍然看不到原始密码。 从能够模拟授权用户的angular度来看,这并不重要,但它可以保护您的用户免于将密码与他们的电子邮件关联在一起。 大多数人不遵循最佳做法,并为他们的许多帐户使用相同的密码,所以这可能是访问者的严重漏洞。

  2. 如果某人以某种方式能够从数据库读取密码(这确实发生了,想想SQL注入),他们仍然不能执行通过我的API模仿用户的特权操作。 这是因为哈希不对称; 即使他们知道存储在数据库中的哈希值,他们也不会知道用来创build它的原始密钥,这就是您的身份validation中间件用来进行身份validation的原因。 这也是为什么你应该总是盐你的散列存储。

当然,如果他们可以自由地从数据库中读取他们想要的东西,他们可能会造成很多其他的损害。

我只想在这里强调一下,如果你决定在离开客户之前把密钥散列出来,那么这是不够的 – 后端哈希是imo更重要,这就是为什么:如果有人拦截了你的stream量客户端,那么他们将看到password字段的内容。 无论这是一个散列还是纯文本,都无关紧要 – 它们可以逐字拷贝模拟授权客户端。 (除非你遵循@ user3299591概述的步骤,我build议你这么做)。 另一方面,抨击数据库专栏是必要的,并不难实施。