简体   繁体   English

如何在php ajax登录加密/盐期间防止捕获

[英]how can I protect against capture during encryption/salt for php ajax login

If a password is encrypted before ajax, what is to stop a hacker from capturing the encrypted password and using it to log in? 如果在ajax之前对密码进行了加密,那么如何阻止黑客捕获加密的密码并使用它登录?

Should a unique salt be sent from the backend beforehand? 是否应该事先从后端发送独特的盐?
Wouldn't a hacker be able to capture that too? 黑客也无法捕获吗?

background to my question: 我的问题的背景:
I worked through this tutorial 我完成了本教程
http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL
summary of tutorial 教程摘要
browser side encrypts password before sending it to backend where it is stored in db 浏览器端在将密码发送到存储在数据库中的后端之前对其进行加密

From that link, the first comment stuck in my mind 通过该链接,我脑海中浮现出第一条评论
"what's to prevent a hacker from capturing the hashed password and logging in?" “如何防止黑客捕获哈希密码并登录?”

Nothing. 没有。 Hashing the password on the client is a terrible idea. 在客户端上散列密码是一个糟糕的主意。

Communication between the browser and server should be properly encrypted using SSL (via HTTPS). 浏览器和服务器之间的通信应使用SSL(通过HTTPS)正确加密。

Hashing on the client side has two effects: 在客户端进行散列有两个作用:

  • It provides a false sense of security to the site owner by suggesting that it can substitute for SSL 通过建议它可以代替SSL,它为网站所有者提供了一种错误的安全感。
  • It adds a dependency on JavaScript 它增加了对JavaScript的依赖

This is a bit silly, really. 真的,这有点愚蠢。 As Quentin stated, all you've done at this point is change what the password is , you havent made it any more secure. 作为昆汀说,你已经在这一点上做的是更改密码什么,你还没有做任何更安全。 Now, instead of the password being 'private string', it is sha1('private string'). 现在,密码不是sha'('private string')。 Which happens to be '5ee913d43470d39020f15ac10ff9cf7a8761b55a' if you hex-encode it. 如果您对它进行十六进制编码,则它恰好是“ 5ee913d43470d39020f15ac10ff9cf7a8761b55a”。

All you've done is trade one password for another. 您要做的就是将一个密码换成另一个。

To exchange passwords securely your best option is to use HTTPS. 为了安全地交换密码,最好的选择是使用HTTPS。 Hands down. 把手放下。 If for some reason you can't get HTTPS working or you don't want to pay for the certificate then you'll have to get creative. 如果由于某种原因您无法使HTTPS正常运行,或者您不想为证书付费,那么您将不得不发挥创意。

Your hardest problem to overcome is the at the initial stage where the user sets their password. 您最需要解决的问题是用户设置密码的初始阶段。 Without using public-key cryptography, your best option is to pass a randomly-generated symmetric key in the form, and use that key to encrypt the password at the client end, and decrypt it at the server end. 在不使用公共密钥加密的情况下,最好的选择是传递形式随机生成的对称密钥,并使用该密钥在客户端对密码进行加密,然后在服务器端对其进行解密。 It can be broken if someone happens to be watching the exchange. 如果有人碰巧正在观看交易,则可能会被打破。 But this is a problem that can't be solved without public key crypto. 但这是没有公钥加密无法解决的问题。

Once the password is set logins can be done very securely. 设置密码后,可以非常安全地完成登录。 When the server renders the login form for the client, it can generate a nonce as part of the form: 当服务器为客户端呈现登录表单时,它可以生成一个随机数作为表单的一部分:

<input type='hidden' name='nonce' value='b45354f5b437c82beeed71d4d56ef3a47d0df2d3'/>
Username: <input type='text' name='username'/><br/>
Password: <input type='password' name='password'/>

Using a Javascript and a crypto library such as crypt-js , the client creates a hashed message. 客户端使用Javascript和加密库(例如crypt-js)创建散列消息。 The message should include a timestamp, the username, and the nonce. 该消息应包括时间戳,用户名和随机数。 Then create an HMAC. 然后创建一个HMAC。

var ts = Math.round((new Date()).getTime() / 1000);
var message = '' + ts + ':' + username + ':' + nonce;
var hash = CryptoJS.HmacSHA1(message, password);

Long story short, the hash is the message hashed together with the password. 长话短说,哈希是将消息与密码哈希在一起的消息。

Now send the message and the hash to the server. 现在,将消息和哈希发送到服务器。 The server has to reverse the process: 服务器必须撤消该过程:

  • parse the message into the nonce, date, and username 将邮件解析为随机数,日期和用户名
  • make sure the nonce was the same one that was given to the client 确保随机数与提供给客户的随机数相同
  • make sure the date is recent (within the last 5 minutes, say) 确保日期是最近的日期(例如过去5分钟内)
  • retrieve the user's password 检索用户密码
  • perform the HMAC computation, and make sure the outcome equals the hash provided by the client. 执行HMAC计算,并确保结果等于客户端提供的哈希值。

The tutorial you posted does not only hash on the client side... they hash on the server side as well. 您发布的教程不仅在客户端进行哈希处理,还在服务器端进行哈希处理。

Basically on that registration page, something JavaScript will hash the user's password and send it to the server. 基本上在该注册页面上,JavaScript会哈希用户密码并将其发送到服务器。 Presumably, this is to stop someone from getting the password in transit. 大概是为了阻止某人获取传输中的密码。 Once the hashed password is sent to the server side, it is salted and hashed again. 一旦将散列的密码发送到服务器端,它将被加密并再次散列。

This method is safe... but I'm not sure I see the merits of hashing on the client if you are using HTTPS, which you should be. 这种方法很安全...但是如果您使用的是HTTPS,我不确定在客户端上看到哈希的好处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM