4

I don't want the server to ever see the raw input and would rather have the client do the encryption and then pass the data (over https) to the server for storage.

If I use a JS library to AES encrypt it what other things do I have to look out for?

Ryan Detzel
  • 151
  • 1
  • 1
  • 3

3 Answers3

4

When this question was asked in 2014, the Web Crypto API did not yet exist. But, now that we have the Web Crypto API, you may want to consider using it instead of one of the libraries referenced in the other answers on this page, for doing in-browser crypto. The Web Crypto API has a CSPRNG implementation, as well as implementations of most common symmetric encryption, asymmetric encryption, hashing, and HMAC functions, all of which you can call from javascript.

However, this still doesn't solve the age-old 'chicken-and-egg' problem when it comes to browser-crypto: `If you can't trust the server with your secrets, then how can you trust the server to serve you secure code?'

mti2935
  • 21,098
  • 2
  • 47
  • 66
4

JavaScript crypto is generally considered a bad idea (see details here )

If you're trying to address the threat of the server being malicious, then the first problem you encounter is "where does the JavaScript that does the encryption come from"?

The usual answer for websites is, "it comes from the server", which leaves you with the problem that if the server is malicious they can just change the JavaScript to give them a a copy of the key required to decrypt the data.

This makes the JavaScript crypto kind of pointless...

Rory McCune
  • 61,541
  • 14
  • 140
  • 221
  • 1
    I've read multiple posts about how the matasano article is full of BS, it's funny how it's quoted as the reason to now use JS encryption though. The server doesn't send secure information to the client, think of the server as storage only. You encrypt the data on the client, pass it off to the storage server and then recall and decrypt. – Ryan Detzel Feb 17 '14 at 16:36
  • 1
    Yes but where does the client get the JavaScript to do the encryption from? the server (in a standard web app). So the server can replace it with malicious JavaScript... so what's the point of the encryption? So the secure information the server sends is the program code used to do the encryption... – Rory McCune Feb 17 '14 at 16:41
  • 1
    As is rather common here, the original question did not really explain what the *objective* of the encryption is. It's quite possible that the model here is that the server acts as a benign secure message drop - and is hence unable to decrypt any messages - but there is the potential that it may be subverted to capture plain text at the point of encryption/decryption. Also it's quite possible for a completely separate server to provide the javascript as provides the storage mechanism. – symcbean Feb 17 '14 at 22:15
  • Symcbean: correct, the server can't decrypt but I can see the issue that if the server was compromised it could just send back bogus JS to send the payload as plaintext to another server. I like the idea of separate servers but that just means they have to hack two servers instead of one. Maybe finding a secure CDN that hosts the JS file so they would have to be hacked. ;-) – Ryan Detzel Feb 18 '14 at 12:01
  • You might want to do this if you don't trust TLS. Arguments to be made for encrypting content during transport. – Ethan Sep 15 '16 at 01:05
  • I think this answer can be generalized to: "Why encrypt data at rest ever?". Because any data that's accessed through some form of automation risks exposure if that automation is compromised. But it still helps in situations where, for example, the data is compromised but not the application server itself. Also, unless all of your users are on the site simultaneously then, even if the app server were exposed, if the data was encrypted you'd have much more time to detect damage and mitigate an attack. You could encrypt data on the server but that's not inherently better. – doliver May 28 '19 at 23:15
3

The recent CIA leaks (and to a lesser extent, Snowden revelations earlier) have convinced me that @rоry-mccune's answer (which I previously believed in as well) is no longer good advice. CIA documents say that protocol downgrade attacks render HTTPS on its own ineffective. Furthermore it's quite possible that even if a party has a servers private keys (enabling both HTTPS surveillance AND alteration / forging) they may not wish to risk revealing that they have the private keys by altering the content via a MITM attack, since the changed content could be detected. Also note that passive surveillance can lead to active compromise. For example, if a password or access token is sent to the server an attacker can then use that password to get further access while not giving away that they've broken a cipher or implemented a passive protocol downgrade attack (passive because they're only surveilling (not altering / forging) - presumably in a dragnet or as part of a botnet of hacked routers / wifi points).

Also, generating a private key client side, sending the public key along with the encrypted message and deleting (or periodically replacing) the private key client side ensures a greater degree of forward secrecy in the event that a cypher is broken.

Other than possibly performance in certain contexts, I fail to see the downside of client side encryption. Yes CSP, preloaded HSTS, and HPKP, TLS 1.2+ are more important and yes if you're pulling in code from elsewhere it can mess with your runtime and yes the random number generator may not be pure enough but the entire argument is hinged on this quote from the linked article:

You can. It's harder than it sounds, but you safely transmit Javascript crypto to a browser using SSL. The problem is, having established a secure channel with SSL, you no longer need Javascript cryptography; you have "real" cryptography. Meanwhile, the Javascript crypto code is still imperiled by other browser problems.

Which the CIA says is not true in leaked classified documents.

Furthermore the Snowden leaks showed how in many instances governments would use lazy dragnets for most sites and targeted attacks for a few (like Google) that were secure enough to cause trouble. If a cipher is secretly broken you'll be better protected by implementing this than if you didn't.

As for what to recommend specifically, I haven't taken the time to vet the alternatives. The author of the linked article mentions this but now that we have what is trying to be a secure random number generator in Chrome and Firefox I think on the whole we're better off trying to encourage more open source developers to secure things than to not try to do so. Just make sure they know it's important to still have TLS.

schroeder
  • 125,553
  • 55
  • 289
  • 326
zachaysan
  • 131
  • 3
  • 2
    Geez, man, if the CIA have multiple teams chasing you, don't come here! They'll follow you here, and then we'll all be in trouble! Hide your donuts, people! – AviD May 10 '17 at 14:55
  • @AviD I get that you're joking, but in reality more and more systems are becoming targets for cyber criminals. Plus the recent Cloudflare leak of HTTPS was telling for one major reason: 1password was saved from password leaking only because they used both TLS and client side encryption, including in the browser: https://blog.agilebits.com/2017/02/23/three-layers-of-encryption-keeps-you-safe-when-ssltls-fails/ the internet isn't going to get more friendly for the foreseeable future. We should standardize our web frameworks to do this automatically for us. – zachaysan May 10 '17 at 23:05
  • 1
    I work in the financial industry, and in our solution we use a "per request" public private key pair to communicate between server and client to protect data and detect tampering & spoofing. – Walter Vehoeven Jan 09 '20 at 21:31