Client-side encryption over HTTP with Diffie-Hellman Key Exchange and AES
Asked Answered
L

3

13

After watching a YouTube video on the Diffie-Hellman Key Exchange, I wanted to try an implementation in JavaScript (Atwood's law).

I sketched up an cipher on Node.js with the following rules:

  • 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)

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?

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!

Lamonica answered 23/3, 2012 at 2:50 Comment(0)
E
6

I've seen questions like this before – this is completely insecure for 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.

In a nutshell, without SSL, you are vulnerable to man-in-the-middle attacks. No browser-based JavaScript crypto implementation can overcome this fact.

Embrangle answered 23/3, 2012 at 3:13 Comment(7)
Hrmm. Assuming I could get the javascript running on the client machine with confidence that it hadn't been modified (possibly an impossible task), would it be any less insecure? I don't think modifications to the data (excluding the applet's initial delivery) would compromise it.Lamonica
Practically speaking, the only way to get JS to the client in a trusted manner is over SSL. And since your connection is already secured, what's the point of doing your own crypto at that point?Embrangle
Renegotiation attacks: openssl.org/news/secadv_20091111.txt, lwn.net/Articles/362234 Cipher downgrade attacks: openssl.org/news/secadv_20101202.txt, wroot.org/posts/preventing-your-servers-from-downgrade-attacksMetronymic
@josh3736, the point could be host-proof hosting (ajaxpatterns.org/Host-Proof_Hosting), for example. Safe-deposit box of sorts, like password manager. But that might not be relevant in the case above.Botany
He never said anything about his work being browser based. He specifically said he was writing this in node.js. Even if he didn't, it could be used in a number of other places and offline apps. Ignoring his question and just telling him that it's completely insecure is very unproductive.Hitt
This is a pretty unconstructive answer, and should not be accepted. The issue of source code provenance is orthogonal to any possible issues around writing DH in JS. This answer is a textbook example of a "middlebrow dismissal": news.ycombinator.com/item?id=4693920. Snarky enough to get upvotes, yet adding nothing to the discussion.Paly
-1 awful and snarky answer. The described scheme is a massive improvement over plain HTTP, since attacking it successfully it requires an active man-in-the-middle attack. In other words, it's only compromisable if some router along the way is compromised. Yes, not ideal, but not exactly common -- when was the last time you experienced spoofed DNS replies, for instance? The question deserves a proper answer.Hix
R
17

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.

  1. How secure is the key exchange?
  2. 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 attack in practice depending on cipher suit choice. And SSL 2.0 is more badly broken.

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.

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 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.

As Josh3737 pointed 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.

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.

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.

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.

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.

Radicle answered 9/5, 2013 at 17:46 Comment(3)
I was actually thinking that DH over HTTPS/TLS could work fairly well... My concerns are potentially corrupt CAs, and that combining DH with an authenticated channel could be at the very least interesting... thanks for your advice on modulus/key lengths, though my bigger concern would be for how nuch time it might take for a browser to compute the shared secret (say on a typical smart phone) in JS.Korney
@Tracker1, when talking about security, there are only two ways to go: take it seriously or don't even consider it. If the data is worth waiting a whole minute, or even more, before starting, then the user will complain, curse and swear, but will wait, otherwise, use something ultra-light-weight, just to keep the laziest of hackers away, because it's not worth the effort, on any side, including the hacker's. Mind you that any "intermediate alternative" is most likely unsafe. My bank's app is slow, hogs memory and sucks to set up, but I'm happy with it, because it's safer than going to a bank.Luminous
@Luminous it's not a matter of how long it takes... it's a matter of it actually working or not... if it kills the browser, than it doesn't work.Korney
E
6

I've seen questions like this before – this is completely insecure for 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.

In a nutshell, without SSL, you are vulnerable to man-in-the-middle attacks. No browser-based JavaScript crypto implementation can overcome this fact.

Embrangle answered 23/3, 2012 at 3:13 Comment(7)
Hrmm. Assuming I could get the javascript running on the client machine with confidence that it hadn't been modified (possibly an impossible task), would it be any less insecure? I don't think modifications to the data (excluding the applet's initial delivery) would compromise it.Lamonica
Practically speaking, the only way to get JS to the client in a trusted manner is over SSL. And since your connection is already secured, what's the point of doing your own crypto at that point?Embrangle
Renegotiation attacks: openssl.org/news/secadv_20091111.txt, lwn.net/Articles/362234 Cipher downgrade attacks: openssl.org/news/secadv_20101202.txt, wroot.org/posts/preventing-your-servers-from-downgrade-attacksMetronymic
@josh3736, the point could be host-proof hosting (ajaxpatterns.org/Host-Proof_Hosting), for example. Safe-deposit box of sorts, like password manager. But that might not be relevant in the case above.Botany
He never said anything about his work being browser based. He specifically said he was writing this in node.js. Even if he didn't, it could be used in a number of other places and offline apps. Ignoring his question and just telling him that it's completely insecure is very unproductive.Hitt
This is a pretty unconstructive answer, and should not be accepted. The issue of source code provenance is orthogonal to any possible issues around writing DH in JS. This answer is a textbook example of a "middlebrow dismissal": news.ycombinator.com/item?id=4693920. Snarky enough to get upvotes, yet adding nothing to the discussion.Paly
-1 awful and snarky answer. The described scheme is a massive improvement over plain HTTP, since attacking it successfully it requires an active man-in-the-middle attack. In other words, it's only compromisable if some router along the way is compromised. Yes, not ideal, but not exactly common -- when was the last time you experienced spoofed DNS replies, for instance? The question deserves a proper answer.Hix
D
1

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.)

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

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
Demosthenes answered 24/1, 2014 at 4:8 Comment(2)
I think I missed something here. On the first step, Client has to receive CERTpublic from Bitcoin Blockchain. Doesn't that come from a server? How will Client be sure that CERTpublic came from Bitcoin Blockchain and not from a Middleman impersonating it?Luminous
Because bitcoin is a solution to the byzantine generals problem. In other words, its possible for the client to be able to tell that the certificate it received is legitimate, due to the way bitcoin works. It's similar to the way that a bitcoin client can tell whether or not a payment was legitimate. Actually this exact use case was implemented in Namecoin. I wrote about it here: sequentialread.com/…Demosthenes

© 2022 - 2024 — McMap. All rights reserved.