just to know, is it possible to send password through an Ajax request safely?
只是要知道,是否可以安全地通过Ajax请求发送密码?
I've a login box that calls an ajax request to try the login/pass and retrieve a JSON Object with errors (if any).
我有一个登录框,调用ajax请求尝试登录/传递并检索有错误的JSON对象(如果有的话)。
Should I use a form redirection instead?
我应该使用表单重定向吗?
[EDIT] Store the encrypted password in the database isn't the solution because the login and password send by ajax are the login / password to access the database itself (internal application).
[编辑]将加密密码存储在数据库中不是解决方案,因为ajax发送的登录名和密码是访问数据库本身的登录名/密码(内部应用程序)。
4 个解决方案
#1
12
The only way to send something that can not be intercepted by a third party is by using HTTPS instead of regular HTTP. That way everything sent between the server and the client is strongly encrypted.
发送无法被第三方拦截的内容的唯一方法是使用HTTPS而不是常规HTTP。这样,服务器和客户端之间发送的所有内容都是高度加密的。
#2
12
For the technical hell of it, you can. If you have access to a one-way cryptographic function crypt(text,key)
that supports crypt(crypt(T,A),B) == crypt(crypt(T,B),A)
you can do the following:
对于它的技术地狱,你可以。如果您可以访问支持crypt(crypt(T,A),B)== crypt(crypt(T,B),A)的单向加密函数crypt(text,key),则可以执行以下操作:
- Have a secret key for your application,
KEY
. Never tell anyone. - When the user registers, store
crypt(password,KEY)
in the database. - When the user wants to log in, send them a randomly generated key
RAND
- The user types the password, the form computes and sends
crypt(password,RAND)
through unsecure AJAX. The password never leaves the user's computer. - The server computes
crypt(crypt(password,RAND),KEY)
from the form response,crypt(crypt(password,KEY),RAND)
from the database, and compares the two. They should be equal.
为您的应用程序准备一个密钥,KEY。别告诉任何人。
当用户注册时,将crypt(密码,KEY)存储在数据库中。
当用户想要登录时,向他们发送随机生成的密钥RAND
用户键入密码,表单计算并通过不安全的AJAX发送crypt(密码,RAND)。密码永远不会离开用户的计算机。
服务器从数据库中的表单响应,crypt(crypt(密码,KEY),RAND)计算crypt(crypt(密码,RAND),KEY),并比较这两者。他们应该是平等的。
All of this is unnecessary complicated an requires a lot of effort to implement correctly and securely. Buying an SSL certificate and using HTTPS is orders of magnitude easier to achieve this level of security, and even more.
所有这些都是不必要的复杂,需要花费很多精力才能正确安全地实施。购买SSL证书和使用HTTPS几个数量级更容易实现这种安全级别,甚至更多。
#3
1
Here's what you could do:
这是你可以做的:
Hash Password and store in database
哈希密码并存储在数据库中
On client side: hash password, then add salt (concatenate session_id string), then hash again
在客户端:哈希密码,然后添加salt(连接session_id字符串),然后再次哈希
On server: take hashed pw from database, then add salt (concatenate session_id string), then hash again
在服务器上:从数据库中取出散列的pw,然后添加salt(连接session_id字符串),然后再次散列
[Edit: and then compare the hash-salt-hash generated on the server with the one sent from the client]
[编辑:然后将服务器上生成的hash-salt-hash与客户端发送的hash-salt-hash进行比较]
Intercepting your hash-salt-hash password is quite useless now, because it is only valid for that particular session...
拦截你的hash-salt-hash密码现在是没用的,因为它只对那个特定的会话有效...
#4
0
What you're looking for is a "zero knowledge protocol". It is a way of communicating that you know a password without sending it. You would communicate between the javascript running in the user's browser, and the server.
您正在寻找的是“零知识协议”。这是一种沟通的方式,你知道密码而不发送它。您将在用户浏览器中运行的javascript与服务器之间进行通信。
Bonus, these protocols are generally secure even if the connection isn't encrypted. Note that it would be stupid to rely on this and not use SSL, because a man in the middle would simply replace your nice zero knowledge protocol implementation with a look-alike function that just sends the password.
奖励,即使连接未加密,这些协议通常也是安全的。请注意,依赖于此并且不使用SSL将是愚蠢的,因为中间的人只需用一个只发送密码的外观相似的函数来替换你的零知识协议实现。
#1
12
The only way to send something that can not be intercepted by a third party is by using HTTPS instead of regular HTTP. That way everything sent between the server and the client is strongly encrypted.
发送无法被第三方拦截的内容的唯一方法是使用HTTPS而不是常规HTTP。这样,服务器和客户端之间发送的所有内容都是高度加密的。
#2
12
For the technical hell of it, you can. If you have access to a one-way cryptographic function crypt(text,key)
that supports crypt(crypt(T,A),B) == crypt(crypt(T,B),A)
you can do the following:
对于它的技术地狱,你可以。如果您可以访问支持crypt(crypt(T,A),B)== crypt(crypt(T,B),A)的单向加密函数crypt(text,key),则可以执行以下操作:
- Have a secret key for your application,
KEY
. Never tell anyone. - When the user registers, store
crypt(password,KEY)
in the database. - When the user wants to log in, send them a randomly generated key
RAND
- The user types the password, the form computes and sends
crypt(password,RAND)
through unsecure AJAX. The password never leaves the user's computer. - The server computes
crypt(crypt(password,RAND),KEY)
from the form response,crypt(crypt(password,KEY),RAND)
from the database, and compares the two. They should be equal.
为您的应用程序准备一个密钥,KEY。别告诉任何人。
当用户注册时,将crypt(密码,KEY)存储在数据库中。
当用户想要登录时,向他们发送随机生成的密钥RAND
用户键入密码,表单计算并通过不安全的AJAX发送crypt(密码,RAND)。密码永远不会离开用户的计算机。
服务器从数据库中的表单响应,crypt(crypt(密码,KEY),RAND)计算crypt(crypt(密码,RAND),KEY),并比较这两者。他们应该是平等的。
All of this is unnecessary complicated an requires a lot of effort to implement correctly and securely. Buying an SSL certificate and using HTTPS is orders of magnitude easier to achieve this level of security, and even more.
所有这些都是不必要的复杂,需要花费很多精力才能正确安全地实施。购买SSL证书和使用HTTPS几个数量级更容易实现这种安全级别,甚至更多。
#3
1
Here's what you could do:
这是你可以做的:
Hash Password and store in database
哈希密码并存储在数据库中
On client side: hash password, then add salt (concatenate session_id string), then hash again
在客户端:哈希密码,然后添加salt(连接session_id字符串),然后再次哈希
On server: take hashed pw from database, then add salt (concatenate session_id string), then hash again
在服务器上:从数据库中取出散列的pw,然后添加salt(连接session_id字符串),然后再次散列
[Edit: and then compare the hash-salt-hash generated on the server with the one sent from the client]
[编辑:然后将服务器上生成的hash-salt-hash与客户端发送的hash-salt-hash进行比较]
Intercepting your hash-salt-hash password is quite useless now, because it is only valid for that particular session...
拦截你的hash-salt-hash密码现在是没用的,因为它只对那个特定的会话有效...
#4
0
What you're looking for is a "zero knowledge protocol". It is a way of communicating that you know a password without sending it. You would communicate between the javascript running in the user's browser, and the server.
您正在寻找的是“零知识协议”。这是一种沟通的方式,你知道密码而不发送它。您将在用户浏览器中运行的javascript与服务器之间进行通信。
Bonus, these protocols are generally secure even if the connection isn't encrypted. Note that it would be stupid to rely on this and not use SSL, because a man in the middle would simply replace your nice zero knowledge protocol implementation with a look-alike function that just sends the password.
奖励,即使连接未加密,这些协议通常也是安全的。请注意,依赖于此并且不使用SSL将是愚蠢的,因为中间的人只需用一个只发送密码的外观相似的函数来替换你的零知识协议实现。