OWASP为什么不建议在客户端和服务器上同时解密密码? [英] Why doesn't OWASP recommend to bcrypt the password both on the client and the server?

查看:108
本文介绍了OWASP为什么不建议在客户端和服务器上同时解密密码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于GitHub和Twitter最近出现的问题:

Since the recent problems with GitHub and Twitter:

  • GitHub Accidentally Recorded Some Plaintext Passwords in Its Internal Logs
  • Twitter Admits Recording Plaintext Passwords in Internal Logs, Just Like GitHub

我想知道,为什么不在客户端和服务器上同时解密密码的最佳实践?由于我不会更改已经是服务器端最佳实践的任何内容(盐,强哈希,HTTPS),因此只能更加安全.服务器将已散列的密码视为密码,并在存储之前再次对其进行散列.

I was wondering, why isn't the best practice to bcrypt the password both on the client and the server? Since I won't change anything that already are the best practices for the server side (salt, strong hash, HTTPS), it can only be safer. The server would consider the already hashed password as the password, and would hash it again before store it.

  • 如果在引发异常时记录了整个请求,如果登录/注册请求中发生异常,我将永远无法访问用户纯文本密码
  • 我知道,如果有人通过MITM(许多公司在其专用网络中替换SSL证书)或日志或恶意服务器管理员访问了这些仅在客户端隐藏的密码,则他们将能够使用它在我的网站中进行身份验证,但无法访问纯文本密码,因此它永远不会损害用户在其他站点和服务中的帐户(即使对于那些重复使用密码的用户)

推荐答案

我正试图解决一个类似的问题,即可以在服务器上记录纯文本密码.结论是,您应该始终对客户端密码进行哈希处理(如果有).

I was looking to resolve a similar issue where plain-text password can be logged on the server. The conclusion is that you should always additionally hash the client password if able.

以下是有关 client-plus-server 哈希的一些文章:

Here is some articles about client-plus-server hashing:

带密码的哈希哈希-正确处理

具体请参阅:

在Web应用程序中,始终在服务器上进行哈希处理

如果您正在编写Web应用程序,则可能想知道在哪里进行哈希处理. 如果使用JavaScript在用户浏览器中对密码进行了哈希处理, 还是应该以明文形式"将其发送到服务器并在其中进行哈希处理?

If you are writing a web application, you might wonder where to hash. Should the password be hashed in the user's browser with JavaScript, or should it be sent to the server "in the clear" and hashed there?

即使您在JavaScript中对用户密码进行哈希处理,您仍然 必须对服务器上的哈希值进行哈希处理.考虑一个散列的网站 在用户浏览器中输入用户密码,而不散列哈希值 服务器.为了验证用户身份,该网站将接受哈希 从浏览器中检查该哈希值是否与 数据库.这似乎比仅在服务器上进行哈希处理更安全, 因为用户的密码永远不会发送到服务器,但不会发送到服务器.

Even if you are hashing the user's passwords in JavaScript, you still have to hash the hashes on the server. Consider a website that hashes users' passwords in the user's browser without hashing the hashes on the server. To authenticate a user, this website will accept a hash from the browser and check if that hash exactly matches the one in the database. This seems more secure than just hashing on the server, since the users' passwords are never sent to the server, but it's not.

问题在于,客户端哈希在逻辑上成为用户的 密码.用户进行身份验证所需要做的就是告诉服务器 他们密码的哈希值.如果一个坏人得到了用户的哈希值,他们可以 使用它来对服务器进行身份验证,而无需了解用户的身份 密码!因此,如果坏人以某种方式窃取了哈希数据库 从这个假设的网站上,他们将可以立即访问 每个人的帐户,而不必猜测任何密码.

The problem is that the client-side hash logically becomes the user's password. All the user needs to do to authenticate is tell the server the hash of their password. If a bad guy got a user's hash they could use it to authenticate to the server, without knowing the user's password! So, if the bad guy somehow steals the database of hashes from this hypothetical website, they'll have immediate access to everyone's accounts without having to guess any passwords.

这并不是说您不应该在浏览器中进行哈希运算,而是 这样做,您绝对也必须在服务器上进行哈希处理.散列 浏览器当然是个好主意,但请考虑以下几点 用于实施:

This isn't to say that you shouldn't hash in the browser, but if you do, you absolutely have to hash on the server too. Hashing in the browser is certainly a good idea, but consider the following points for your implementation:

客户端密码哈希不能替代HTTPS(SSL/TLS).如果浏览器和服务器之间的连接是 不安全的中间人可以按原样修改JavaScript代码 下载以删除哈希功能并获取用户的 密码.

Client-side password hashing is not a substitute for HTTPS (SSL/TLS). If the connection between the browser and the server is insecure, a man-in-the-middle can modify the JavaScript code as it is downloaded to remove the hashing functionality and get the user's password.

某些网络浏览器不支持JavaScript,某些用户在其浏览器中禁用了JavaScript.因此,为了获得最大的兼容性,您的应用 应该检测浏览器是否支持JavaScript,并且 如果没有,则在服务器上模拟客户端哈希.

Some web browsers don't support JavaScript, and some users disable JavaScript in their browser. So for maximum compatibility, your app should detect whether or not the browser supports JavaScript and emulate the client-side hash on the server if it doesn't.

您还需要添加客户端哈希.显而易见的解决方案是使客户端脚本向服务器询问用户的要求. 不要这样做,因为它会让坏人检查用户名是否为 在不知道密码的情况下仍然有效.由于您正在哈希和加盐 (在服务器上放好盐),也可以使用用户名(或 电子邮件)与特定于站点的字符串(例如域名)连接为 客户端盐.

You need to salt the client-side hashes too. The obvious solution is to make the client-side script ask the server for the user's salt. Don't do that, because it lets the bad guys check if a username is valid without knowing the password. Since you're hashing and salting (with a good salt) on the server too, it's OK to use the username (or email) concatenated with a site-specific string (e.g. domain name) as the client-side salt.

经过研究,似乎在对客户端进行哈希处理方面也有明显的安全性好处.如果HTTPS上的密码被盗用,或者该密码已记录在服务器上,则纯文本密码将无法轻易地在用户的其他帐户上重用(许多用户重用了他们的密码).

After researching, it seems that there is a clear security benefit in hashing the client as well. If the password over HTTPS is compromised or if the password is logged on the server, then the plain-text password could not be easily reused on the user's other accounts (many users reuse their passwords).

唯一可能的缺点是客户端性能和服务器端密码验证.用户可以操纵您的客户端JS并提交弱"密码.服务器再也不会知道了.但是我认为这是一个小问题,它依赖于人们有意修改其客户端代码以削弱其自身的安全性.

The only possible downside is client performance, and server-side password validation. A user can manipulate your client JS and submit a "weak" password. The server wouldn't know any better. But I think this is a small issue, and it relies on people intentionally modifying their client code in order to weaken their own security.

这篇关于OWASP为什么不建议在客户端和服务器上同时解密密码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆