简体   繁体   English

如何在没有HTTPS的情况下使用Javascript通过HTTP安全地发送密码?

[英]How to send password securely via HTTP using Javascript in absence of HTTPS?

The very basic issue all developers face: Whenever user submits the form, the password is sent via network and it must be protected. 所有开发人员都面临的一个非常基本的问题:每当用户提交表单时,密码都会通过网络发送,并且必须受到保护。 The site I develop for doesn't have HTTPS. 我开发的网站没有HTTPS。 Neither does the owner want to buy a SSL certificate, nor is he interested in a self-signed one. 所有者既不想购买SSL证书,也不想对自签名证书感兴趣。 So I want to protect the password sent via HTTP using Javascript when submitting form. 所以我想在提交表单时使用Javascript保护通过HTTP发送的密码。

To eager downvoters: How to send password securely over HTTP? 渴望downvoters: 如何通过HTTP安全地发送密码? DOES NOT give any sensible solution and I am in another situation. 不提供任何合理的解决方案,我处于另一种情况。

If I use MD5, one can reverse that password string. 如果我使用MD5,可以反转该密码字符串。 What about nonce/HMAC? 那怎么样的nonce / HMAC? Any available Javascript library for that? 任何可用的Javascript库吗? Or do you have any suggestion/hint to tackle? 或者你有什么建议/提示要解决? Thanks in advance! 提前致谢!

There is no way to send a password securely that the user can verify without SSL. 无法安全地发送密码,用户可以在没有SSL的情况下验证密码。

Sure, you can write some JavaScript that will make a password secure for over-the-wire transmission through hashing or public-key-encryption. 当然,您可以编写一些JavaScript,通过散列或公钥加密,使密码安全,实现线上传输。 But how can the user be sure that the JavaScript itself has not been tampered with by a man-in-the-middle before it reached them, to send the password to an attacker instead of the site, or even just compromise the security of the algorithm? 但是,用户如何确保JavaScript本身在到达它们之前没有被中间人篡改,将密码发送给攻击者而不是网站,甚至只是破坏了安全性。算法? The only way would be for them to be expert programmers and have them inspect every line of your page and script to ensure it was kosher before typing the password. 唯一的方法是让他们成为专家程序员,让他们检查你的页面和脚本的每一行,以确保在输入密码之前它是犹太人。 That is not a realistic scenario. 这不是一个现实的情况。

If you want passwords to be safe from man-in-the-middle attacks, you must buy an SSL cert. 如果您希望密码免受中间人攻击,则必须购买SSL证书。 There is no other way. 没有其他办法。 Get used to it. 习惯它。

If I use MD5, one can reverse that password string. 如果我使用MD5,可以反转该密码字符串。

No... not trivially at least. 不......至少不是琐碎的。 Whilst MD5 has attacks against it, it's a hashing algorithm and thus unreversable. 虽然MD5对它有攻击,但它是一种哈希算法,因此是不可逆转的。 You would have to brute-force it. 你必须蛮力。

But again, a man-in-the-middle attacker doesn't need to look at your MD5s. 但同样,一个中间人攻击者不需要看你的MD5。 He can simply sabotage the JavaScript you send the user to make the MD5s. 他可以简单地破坏你发送给用户制作MD5的JavaScript。

The solution here is to not send the password at all. 这里的解决方案是根本不发送密码。 Use challenge/response. 使用挑战/回应。

In the original form include a large block of random text along with a key. 在原始形式中包括一大块随机文本和一个键。 Store the original random text in the session based on key on the server. 根据服务器上的密钥将原始随机文本存储在会话中。 When the client submits the form, use JS to hash the random text and password together. 当客户端提交表单时,使用JS将随机文本和密码一起散列。 Then send the username, key, and hashed random text to the server. 然后将用户名,密钥和散列随机文本发送到服务器。 DO NOT send the password. 请勿发送密码。 On the server, use the key to lookup the original random text, perform the same hashing operation with the stored password. 在服务器上,使用密钥查找原始随机文本,使用存储的密码执行相同的散列操作。 If the server-hashed value matches the client hashed value, then you know the client entered the right password without ever sending the password to the server. 如果服务器散列值与客户端散列值匹配,则您知道客户端输入了正确的密码,而没有将密码发送到服务器。

Whether the password is right or not, expire the key and random text so each are one-time-use. 密码是否正确,密钥和随机文本到期,因此每个密码都是一次性使用。

If you REALLY want to deep-dive into this, look at the Diffie-Hellman key exchange which was created to "allow two parties that have no prior knowledge of each other to jointly establish a shared secret key over an insecure communications channel" 如果您真的想深入研究这一点,请查看Diffie-Hellman密钥交换 ,该密钥交换是为了“允许彼此之前没有相关知识的两方在不安全的通信信道上共同建立共享密钥”而创建的

I'm not a cryptography expert though, so I don't fully know if it's really secure if an attacker has both the Client (JavaScript source code) and the transport mechanism (Packet sniffer) 我不是加密专家,所以如果攻击者同时拥有客户端(JavaScript源代码)和传输机制(数据包嗅探器),我不完全知道它是否真的安全

You can use a javascript RSA implementation to encrypt the password before sending. 您可以在发送之前使用javascript RSA实现来加密密码。 (Here is an example of RSA In Javascript .) (这是RSA在Javascript中的一个例子。)

But I believe both this one and using a hash function will be vulnerable to replay attacks . 但我相信这一个并使用哈希函数将容易受到重放攻击 So, be careful. 所以,要小心。

Unfortunately there will be no way to ensure security of a non-encrypted request. 遗憾的是,无法确保未加密请求的安全性。 Anyone with access to your javascript will simply be able to reverse engineer it/tamper with it and anyone with a packet sniffer will be able to watch the unencrypted traffic. 任何能够访问您的JavaScript的人都可以简单地对其进行反向工程/篡改它,任何拥有数据包嗅探器的人都可以观看未加密的流量。 These two facts together mean: 这两个事实共同意味着:

No SSL? 没有SSL? No security. 没有安全感。

Any transmission that you have will be in the clear; 你拥有的任何传输都将是明确的; that is, without SSL your critical information will be exposed. 也就是说,没有SSL,您的关键信息就会暴露出来。 It is worth discussing that point with the site Owner. 值得与网站所有者讨论这一点。 In other words, it's best to take necessary measure to fortify your data transmission, and SSL is one the basic, cheap steps you can take. 换句话说,最好采取必要的措施来强化数据传输,SSL是您可以采取的基本,廉价步骤之一。

i don't think the issue here is the technology, but how you explain the importance of SSL. 我认为这里的问题不是技术,而是你如何解释SSL的重要性。 Provide them with reliable reading materials, i'm sure there are plenty over the web. 为他们提供可靠的阅读材料,我相信网上有很多。

The solution requires the client to be able to encrypt the password using a secret encryption key known only to the client and the server. 该解决方案要求客户端能够使用仅为客户端服务器知道的秘密加密密钥来加密密码。

SSL accomplishes this by requiring both the server and the client web browser to have their own asymmetric public/private keypair, which they use to encrypt and transmit a random session key between them. SSL通过要求服务器和客户端Web浏览器都拥有自己的非对称公钥/私钥对来实现这一点,它们用于加密和传输它们之间的随机会话密钥。 The rest of the conversation then uses that secure session key. 然后,对话的其余部分使用该安全会话密钥。

So you're asking how to solve the same problem as SSL without the benefit of having a secret key that is known only to the client and server. 因此,您正在询问如何解决与SSL相同的问题,而无需拥有仅为客户端和服务器所知的密钥。 I'm no expert, but it looks like this can't be done, or at least not easily. 我不是专家,但看起来这样做不可能,或者至少不容易。

If you don't have access to SSL, MD5 should be adequate to prevent accidental discovery of passwords (such as in a network log file or something). 如果您无法访问SSL,则MD5应足以防止意外发现密码(例如在网络日志文件或其他内容中)。 Anything else would be a waste of time. 别的什么都浪费时间。 Just make sure the app doesn't give access to sensitive information (ie, credit card numbers, medical history, etc). 只需确保该应用无法访问敏感信息(即信用卡号,病史等)。

Like others commenters have suggested, a serious attacker will be able to break any type of security on the page. 与评论者提出的其他人一样,严重的攻击者将能够打破页面上的任何类型的安全性。 Even SSL is a small barrier since most users use easy-to-guess passwords, re-use the same passwords everywhere, will give their password to anybody that asks, or can be tricked into giving up their password by a copied page or "tech support" phone call. SSL甚至是一个小障碍,因为大多数用户使用易于猜测的密码,在任何地方重复使用相同的密码,将密码提供给任何要求的人,或者可能被欺骗通过复制的页面或“技术”放弃密码支持“电话。

-- English -- i think in something, but i don't know if it could be really secure. - 英语 - 我想某事,但我不知道它是否真的安全。 If you can put your form in a php file, then you can create an algoritm for create a string based in time or in something else, and then put this string in your html. 如果你可以将你的表单放在一个php文件中,那么你可以创建一个algoritm来创建一个基于时间或其他东西的字符串,然后把这个字符串放在你的html中。

When the user type a password in a password input field, when you debug it you canot see the value typed by user, so before send the information via post or get, you can use the password user as a hint to encrypt the encrypted string previosly generated, and then, just sent it insted of the password typed by user. 当用户在密码输入字段中输入密码时,当您调试密码时,您可以看到用户输入的值,因此在通过post或get发送信息之前,您可以使用密码用户作为提示来加密加密的字符串。生成,然后,只是发送了由用户输入的密码。

In this way, the attackers dont have all inside the js code, so they will need discover the algoritm that you create to decrypt it. 通过这种方式,攻击者不会拥有js代码中的所有内容,因此他们需要发现您创建的算法来解密它。

This is just an idea, so if you can tell me how this can not be safe, I would appreciate it. 这只是一个想法,所以如果你能告诉我这怎么不安全,我将不胜感激。

-- Spanish -- Se me acaba de ocurrir algo que puede servir, pero no se si realmente sea algo seguro. - 西班牙语 - Se me acaba de ocurrir algo que puede servir,pero no se si realmente sea algo seguro。 Por medio de php puedes generar un algoritmo que cree un string en base al timestamp o algo más, y después colocar esta cadena en el html. 来自medio de php puedes generar un algoritmo que cree un string en base al timestamp oalgomás,ydespuéscolocaresta cadena en el html。

Note que cuando alguien escribe una contraseña en un campo input tipo password, con un debug no se puede ver el valor que tecleo el usuario (no se si exista manera pero no quise investigar más), asi que podemos utilizar la contraseña que el usuario escribió como palabra clave para encriptar la cadena de texto que previamente habiamos generado con php, por medio de un algoritmo en JS. 注意que cuando alguien escribeunacalconseñaenun campo输入tipo密码,con un debug puede ver el valor que tecleo el usuario(no se si exista manera pero no quiseinvestigarmás),asi que podemos utilizarlacontraseñaqueelusuarioescribió como palabra clave para encriptar la cadena de texto que previamente habiamos generado con php,por medio de un aligitmo en JS。 Sería algo así como encriptar lo encriptado. Seríaalgoasícomoencriptar lo encriptado。 Posteriormente lo que estariamos enviado no sería la contraseña tecleada, si no esta última cadena resultante. Posteriormente lo que estariamos enviadonoseríalacontactñaetecada,si noestaúltimacadenaresultante。

Buscando un contra, lo único que se me ocurra es que el atacante tendrá que dedicarle mucho tiempo para tratar de encontrar el agoritmo que creamos por medio de php y poder decriptar la cadena final, o tendrá que hackear el servidor para acceder al php y obtener el algoritmo. Buscando un contra,loúnicocouse me ocurra es que elatacantetendráquedinadlemucho tiempo para tratar de encontrar el agoritmo que creamos por medio de php y poder decriptar la cadena final,otendráquehackear el servidor para acceder al php y obtener el algoritmo。

Esto es solo una idea, por lo que si pueden decirme como esto puede no ser seguro, se los agradecería. Esto es solo una idea,por lo que si pueden decirme como esto puede no ser seguro,selosagradecería。

As mentioned, none of this is secure against server spoofing, as that requires an ability to trust the client-side Javascript. 如上所述,这对于服务器欺骗都不是安全的,因为这需要能够信任客户端Javascript。 But if we're sure that the server can't be spoofed (signed cert, hash signing immune to length-extension, etc.) but not that the connection is immune to eavesdroppers, here's how I'd implement it. 但是如果我们确定服务器不能被欺骗(签名证书,哈希签名不受长度扩展等影响),而不是连接对窃听者免疫,这就是我实现它的方式。

I think the most secure way is, instead of storing H( password ), where H is your hash function of choice, store g^H( password ) ie use the password as the private key for Diffie-Hellman key exchange. 我认为最安全的方式是,而不是存储H( 密码 ),其中H是您选择的哈希函数,存储g ^ H( 密码 )即使用密码作为Diffie-Hellman密钥交换的私钥。 (You should also probably use a random g for different users, too--it becomes your salt.) Then to verify, you generate a nonce b, send the user g^b, and compute (g^H( password ))^b. (你也应该为不同的用户使用随机g - 它变成了你的盐。)然后验证,你生成一个nonce b,发送用户g ^ b,并计算(g ^ H( 密码 ))^湾 The user does not need to know g--they need only compute (g^b)^H( password ) = (g^H( password ))^b. 用户不需要知道g - 他们只需要计算(g ^ b)^ H( 密码 )=(g ^ H( 密码 ))^ b。 Now you have a number that both parties know iff the user entered the right password, and constructing a challenge-response zero-knowledge proof based on knowing the correct number is trivial, while the random number used as the server's "private key" makes the approach immune to replay attacks. 现在你有一个双方知道的号码, 如果用户输入了正确的密码,并且基于知道正确的号码构建质询 - 响应零知识证明是微不足道的,而用作服务器的“私钥”的随机数使得接近免疫重放攻击。

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

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