客户端密码加密
可能的重复:
关于客户端的密码哈希系统
我必须保护我的网站用户。我所做的是在服务器端使用 MD5 加密 哈希。但问题是密码在到达服务器之前一直保持纯文本形式,这意味着可以使用流量监控捕获密码。所以我想要的是使用客户端密码加密/哈希机制并发送加密/哈希密码。 谁能告诉我有什么方法可以做到这一点吗?
Possible Duplicate:
About password hashing system on client side
I have to secure the passwords of my web site users. What I did was use MD5 encryption hashing in server side. But the problem is the passwords remain in plain text until it arrives at the server, which means that the password can be captured using traffic monitoring. So what I want is to use a client side password encryption/hashing mechanism and send the encrypted/hashed password.
Can anybody tell what is the way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
对于类似的情况,我使用了PKCS #5:基于密码的加密标准 来自 RSA 实验室。您可以避免存储密码,方法是将其替换为只能从密码生成的内容(一句话)。有一些 JavaScript 实现。
For a similar situation I used this PKCS #5: Password-Based Cryptography Standard from RSA laboratories. You can avoid storing password, by substituting it with something that can be generated only from the password (in one sentence). There are some JavaScript implementations.
这种保护通常通过使用 HTTPS 来提供,以便 Web 服务器和 Web 服务器之间的所有通信客户端已加密。
有关如何实现此目的的确切说明取决于您的网络服务器。
Apache 文档有一个 SSL 配置方法 指南,可以能有一些帮助。 (感谢用户 G.Qyy 提供的链接)
This sort of protection is normally provided by using HTTPS, so that all communication between the web server and the client is encrypted.
The exact instructions on how to achieve this will depend on your web server.
The Apache documentation has a SSL Configuration HOW-TO guide that may be of some help. (thanks to user G. Qyy for the link)
我在底部列出了用于创建 MD5 的完整 JavaScript,但由于多种原因,如果没有安全连接,它实际上毫无意义。
如果您对密码进行 MD5 并将该 MD5 存储在数据库中,则 MD5 就是密码。人们可以准确地知道您的数据库中有什么。您实际上只是将密码设置为更长的字符串,但如果您将其存储在数据库中,它仍然不安全。
如果您说“好吧,我将对 MD5 进行 MD5”,那么您就没有抓住要点。通过查看网络流量或查看您的数据库,我可以欺骗您的网站并向其发送 MD5。当然,这比仅仅重复使用纯文本密码要困难得多,但它仍然是一个安全漏洞。
最重要的是,如果不通过未加密的网络发送盐,就无法对哈希客户端进行加盐,因此加盐毫无意义。在没有盐或已知盐的情况下,我可以暴力攻击哈希值并找出密码是什么。
如果您打算通过未加密的传输来执行此类操作,则需要使用公钥/私钥加密技术。客户端使用您的公钥进行加密,然后您使用您的私钥进行解密,然后对密码进行 MD5(使用用户唯一的盐)并将其存储在您的数据库中。这是JavaScript GPL 公钥/私钥库。
无论如何,这里是创建 MD5 客户端的 JavaScript 代码(不是我的代码):
I've listed a complete JavaScript for creating an MD5 at the bottom but it's really pointless without a secure connection for several reasons.
If you MD5 the password and store that MD5 in your database then the MD5 is the password. People can tell exactly what's in your database. You've essentially just made the password a longer string but it still isn't secure if that's what you're storing in your database.
If you say, "Well I'll MD5 the MD5" you're missing the point. By looking at the network traffic, or looking in your database, I can spoof your website and send it the MD5. Granted this is a lot harder than just reusing a plain text password but it's still a security hole.
Most of all though you can't salt the hash client side without sending the salt over the 'net unencrypted therefore making the salting pointless. Without a salt or with a known salt I can brute force attack the hash and figure out what the password is.
If you are going to do this kind of thing with unencrypted transmissions you need to use a public key/private key encryption technique. The client encrypts using your public key then you decrypt on your end with your private key then you MD5 the password (using a user unique salt) and store it in your database. Here's a JavaScript GPL public/private key library.
Anyway, here is the JavaScript code to create an MD5 client side (not my code):
您已使用 ssl 标签标记此问题, SSL 就是答案。好奇的。
You've tagged this question with the ssl tag, and SSL is the answer. Curious.
您还可以简单地将 http 身份验证 与 摘要 (如果您使用 Apache httpd,这里有一些信息,Apache Tomcat,这里有一个解释摘要)。
对于 Java,有关有趣的信息,请查看:
You can also simply use http authentication with Digest (Here some infos if you use Apache httpd, Apache Tomcat, and here an explanation of digest).
With Java, for interesting informations, take a look at :
有可用于 JavaScript 的 MD5 库。请记住,如果您需要支持没有 JavaScript 可用的用户,则此解决方案将不起作用。
更常见的解决方案是使用 HTTPS。使用 HTTPS,SSL 加密是在您的 Web 服务器和客户端之间协商的,透明地加密所有流量。
There are MD5 libraries available for javascript. Keep in mind that this solution will not work if you need to support users who do not have javascript available.
The more common solution is to use HTTPS. With HTTPS, SSL encryption is negotiated between your web server and the client, transparently encrypting all traffic.
这并不安全,原因很简单:
如果您在客户端对密码进行哈希处理并使用该令牌而不是密码,那么攻击者将不太可能找出密码是什么。
但是,攻击者不需要找出密码是什么,因为您的服务器不再需要密码 - 它需要令牌。攻击者确实知道该令牌,因为它是通过未加密的 HTTP 发送的!
现在,可能可以将某种质询/响应形式的加密组合在一起,这意味着相同的密码将在每个请求中生成不同的令牌。然而,这将要求密码以可解密的格式存储在服务器上,这并不理想,但可能是一个合适的折衷方案。
最后,您真的希望用户在登录您的网站之前先打开 JavaScript 吗?
无论如何,SSL 不再是一种昂贵或特别难以设置的解决方案
This won't be secure, and it's simple to explain why:
If you hash the password on the client side and use that token instead of the password, then an attacker will be unlikely to find out what the password is.
But, the attacker doesn't need to find out what the password is, because your server isn't expecting the password any more - it's expecting the token. And the attacker does know the token because it's being sent over unencrypted HTTP!
Now, it might be possible to hack together some kind of challenge/response form of encryption which means that the same password will produce a different token each request. However, this will require that the password is stored in a decryptable format on the server, something which isn't ideal, but might be a suitable compromise.
And finally, do you really want to require users to have javascript turned on before they can log into your website?
In any case, SSL is neither an expensive or especially difficult to set up solution any more
您需要一个可以在客户端加密您的输入并将其以加密形式传输到服务器的库。
您可以使用以下库:
3 年后更新 (2013):
4 年后更新年(2014 年):
You need a library that can encrypt your input on client side and transfer it to the server in encrypted form.
You can use following libs:
Update after 3 years (2013):
Update after 4 years (2014):
我会选择 这个简单的解决方案。
总结一下:
#S
并发送给客户端h(pw)
(这是存储在数据库中的内容)#C
h(pw) + #S + #C
并计算其哈希值,称之为h(all)
用户名
、#C
和h(all)
用户名
的h(pw)'
h(all')
的所有元素,就像客户端所做的那样h(all)
=h(all')
则h(pw)
=h(pw)'< /code>,几乎可以肯定
没有人可以重复以指定用户身份登录的请求。
#S
每次都会向哈希添加一个变量组件(这是基础)。#C
在其中添加了额外的噪音。I would choose this simple solution.
Summarizing it:
#S
and sends it to the Clienth(pw)
(which is what is stored in the DB)#C
h(pw) + #S + #C
and calculates its hash, call ith(all)
username
,#C
andh(all)
h(pw)'
for the specifiedusername
, from the DBh(all')
, like Client didh(all)
=h(all')
thenh(pw)
=h(pw)'
, almost certainlyNo one can repeat the request to log in as the specified user.
#S
adds a variable component to the hash, each time (it's fundamental).#C
adds additional noise in it.