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

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

问题描述

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

Since the recent problems with GitHub and Twitter:

我想知道,为什么最好不要在客户端和服务器上同时加密密码?由于我不会更改任何已经是服务器端最佳实践的东西(盐、强哈希、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.

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

客户端密码散列不能替代 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 不建议在客户端和服务器上都对密码进行 bcrypt?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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