javascript 使用 Diffie-Hellman 密钥交换和 AES 通过 HTTP 进行客户端加密
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9833527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Client-side encryption over HTTP with Diffie-Hellman Key Exchange and AES
提问by iRyanBell
After watching a YouTube video on the Diffie-Hellman Key Exchange, I wanted to try an implementation in JavaScript (Atwood's law).
在观看了Diffie-Hellman Key Exchange上的 YouTube 视频后,我想尝试用 JavaScript(阿特伍德定律)实现。
I sketched up an cipher on Node.js with the following rules:
我使用以下规则在 Node.js 上草拟了一个密码:
Step 1: Client and server agree on a shared key:
Client & server start with a 512bit prime public key pK
Client generates a 512bit prime private key kC and sends powMod(3, kC, pK)
Server generates a 512bit prime private key kS and sends powMod(3, kS, pK)
Client & Server use powMod(response, privatekey, pK) as the shared key
Step 2: Communication
Before a client sends data it is encrypted with the shared key using the Stanford Javascript Crypto Library (256bit AES, HMAC authentication, PBKDF2 password strengthening, and CCM authenticated-encryption.)
Once the server decrypts the data with the shared key, it generates a new 512bit prime private key and sends it as a SJCL encrypted response.
The client and server switch to a new shared key using powMod(3, prevSharedKey, newPrivKey)
第 1 步:客户端和服务器就共享密钥达成一致:
客户端和服务器以 512 位质数公钥 pK 开始
客户端生成 512 位素数私钥 kC 并发送 powMod(3, kC, pK)
服务器生成一个512bit的素数私钥kS并发送powMod(3, kS, pK)
Client & Server 使用 powMod(response, privatekey, pK) 作为共享密钥
第 2 步:沟通
在客户端发送数据之前,它使用斯坦福 Javascript 加密库(256 位 AES、HMAC 身份验证、PBKDF2 密码强化和 CCM 身份验证加密)使用共享密钥进行加密。
服务器使用共享密钥解密数据后,它会生成一个新的 512 位主私钥,并将其作为 SJCL 加密响应发送。
客户端和服务器使用 powMod(3, prevSharedKey, newPrivKey) 切换到新的共享密钥
Now I have a few questions..
现在我有几个问题..
How secure would such a system be in comparison with HTTPS or other algorithms? What are the weakest points of such a system?
与 HTTPS 或其他算法相比,这样的系统有多安全?这种系统的最弱点是什么?
In terms of security / practicality, would it be better to use 1024 bit keys for stronger security? Are the HMAC/PBKDF2/CCM options overkill? Is it worth modulating the shared key? Thanks for reading!
在安全性/实用性方面,使用 1024 位密钥以获得更强的安全性会更好吗?HMAC/PBKDF2/CCM 选项是否过大?是否值得调制共享密钥?谢谢阅读!
采纳答案by josh3736
I've seen questions like this before– this is completely insecurefor a number of reasons, foremost of which is the fact that it is impossible for a JavaScript client to verify that the server's key is authentic.
我见过这样的问题面前-这是完全不安全的许多原因,其中最主要的是事实,这是不可能的JavaScript客户端验证服务器的密钥是真实的。
In a nutshell, without SSL, you are vulnerable to man-in-the-middle attacks. No browser-based JavaScript crypto implementation can overcome this fact.
简而言之,如果没有 SSL,您很容易受到中间人攻击。没有基于浏览器的 JavaScript 加密实现可以克服这个事实。
回答by Jeffrey Goldberg
Your system is massively insecure, but I'm not trying to dissuade you or anyone from playing around with stuff like this. You should continue to. But it is vital that you consider anything you create to be a "toy" system that should never be considered or advertised as "secure".
你的系统非常不安全,但我并不是要劝阻你或任何人玩这样的东西。你应该继续。但至关重要的是,您将创建的任何东西都视为“玩具”系统,永远不应将其视为或宣传为“安全”。
Let's break down the security question into two parts.
让我们将安全问题分为两部分。
- How secure is the key exchange?
- How secure is the encryption you use once you've got a shared key?
- 密钥交换的安全性如何?
- 获得共享密钥后,您使用的加密有多安全?
Let me answer (2) first as that will be the simplest. It will be terribly insecure unless you are smarter than all of the people who've worked on and studied TLS over the years. TLS before version 1.2 (which few sites use) is vulnerable to Chosen Ciphertext Attacks (CCAs) in principle and to the BEAST attackin practice depending on cipher suit choice. And SSL 2.0 is more badly broken.
让我先回答(2),因为那将是最简单的。除非您比多年来从事和研究 TLS 的所有人都更聪明,否则它将非常不安全。1.2 版之前的 TLS(很少有网站使用)原则上容易受到选择密文攻击 (CCA) 的攻击,而在实践中,根据密码套装的选择,容易受到BEAST 攻击。而 SSL 2.0 被破坏得更严重。
The point is that very very smart people, working on these protocols over years, got some things wrong. There is every reason to believe that you are I working on these sorts of things on our own will make huge mistakes. The basic encryption algorithms are fine. They aren't broken. But the protocols are.
关键是非常非常聪明的人,在这些协议上工作了多年,但犯了一些错误。有充分的理由相信你是我自己的工作会犯下巨大的错误。基本的加密算法很好。他们没有坏。但协议是。
So if you haven't studied and fully understood all of the details of SSL, why they are there and how they have gone wrong in some cases, then it is almost certain that any protocol you devise will be terrible.
因此,如果您还没有研究并完全理解 SSL 的所有细节、它们为何存在以及它们在某些情况下如何出错,那么几乎可以肯定您设计的任何协议都会很糟糕。
Now to question (2). There are two issues with this. (a) Diffie-Hellman is not designed to provide the sorts of security you probably need; and (b) I don't think that you've implemented DH correctly.
现在回答问题(2)。这有两个问题。(a) Diffie-Hellman 并非旨在提供您可能需要的那种安全性;(b) 我认为您没有正确实施 DH。
2.a:
2.a:
Diffie-Hellman Key exchange, when done right, is secure for key exchange, but it does nothing for authentication. This is why the question "is it secure" is often the wrong question. It is secure for some purposes, but massively insecure for others as it isn't designed for those other purposes.
Diffie-Hellman 密钥交换,如果做得好,对于密钥交换是安全的,但它对身份验证没有任何作用。这就是为什么“它是否安全”的问题通常是错误的问题。它对于某些目的是安全的,但对于其他目的却非常不安全,因为它不是为其他目的而设计的。
As Josh3737pointed out, there is no way for the client and the server to know that they are talking to the right party. If Sam is the server and Charlie is the Client, there is nothing that stops Mallory from setting up her own server that masquerades as Sam. So Cathy can go through the key exchange with Mallory, thinking that she is talking to Sam. Mallory can pretend to be Charlie when talking to Sam.
正如Josh3737指出的那样,客户端和服务器无法知道他们正在与正确的一方交谈。如果 Sam 是服务器而 Charlie 是客户端,则没有什么可以阻止 Mallory 设置自己的伪装成 Sam 的服务器。所以凯茜可以通过与马洛里的密钥交换,认为她是在和山姆说话。马洛里在和山姆说话时可以假装是查理。
Once set up this way, Mallory can act as a Man In The Middle between Sam and Charlie. When Charlie sends data intended to Sam, Mallory will decrypt it using the shared key between C and M, read it (and possibly change it), and then re-encrypt it the the shared key between M and S and send that off to S.
以这种方式设置后,马洛里就可以充当山姆和查理之间的中间人。当 Charlie 向 Sam 发送数据时,Mallory 将使用 C 和 M 之间的共享密钥对其进行解密,读取它(并可能更改它),然后使用 M 和 S 之间的共享密钥重新加密它并将其发送给 S .
To solve the authentication problem, you need some sort of Public Key Infrastructure (PKI) and these are really a pain. The system of Certificate Authorities and such that we have with SSL/TLS is fraught with problems, but it remains the best system out there.
要解决身份验证问题,您需要某种公钥基础设施 (PKI),而这些确实很痛苦。证书颁发机构系统以及我们使用 SSL/TLS 的系统充满了问题,但它仍然是最好的系统。
2.b:
2.b:
A 512 bit public modulus along with 512 bit private keys are not strong enough. DH keys need to be bigger. I wouldn't go with anything less than 2048 bits. You might get away with 1024 bits you aren't worried about someone being able to break today's secrets five years from now.
512 位公共模数和 512 位私钥不够强大。DH 密钥需要更大。我不会使用小于 2048 位的任何东西。您可能会使用 1024 位,您不必担心五年后有人能够破解今天的秘密。
You didn't give enough information on how your primes were selected. Not every prime will work. You need to use a "safe prime" for your modulus, otherwise there are shortcuts available for an attacker to compute the discrete logarithm.
您没有提供有关如何选择素数的足够信息。不是每个素数都会起作用。您需要为模数使用“安全素数”,否则攻击者可以使用快捷方式来计算离散对数。
回答by daftuser
If you want to get around the SSL cert and man in the middle problem, you can use the bitcoin blockchain. (Or an altcoin blockchain.)
如果你想绕过 SSL 证书和中间问题,你可以使用比特币区块链。(或山寨币区块链。)
The Huge Caveat: the client has to either download or maintain an entire file of the blockchain.
巨大的警告:客户端必须下载或维护区块链的整个文件。
There are two public/private key pairs:
有两个公钥/私钥对:
CERTpublic CERTprivate
CERTpublic CERTprivate
CLIENTpublic CLIENTprivate
CLIENTpublic CLIENTprivate
NAME REGISTRATION:
姓名注册:
Server -> CERTpublic and name_to_register -> Bitcoin Blockchain
AUTHENTICATED CONNECTION:
经认证的连接:
Client <- CERTpublic <- Bitcoin Blockchain
Client -> CERTpublic(CLIENTpublic) -> Server or Adversary
Client <- No_response_or_incorrect <- Adversary
Client <- CLIENTpublic(CERTprivate(content)) <- Server