Encrypting Files in JavaScript Before Sending Them to Google Storage
I am looking into allowing user of our website to upload their file directly to GCE storage without sending the file to our server.
But we want the file to first be encrypted before saving it on GCE.
The client does not need access to the file nor the encryption key it generated once it is done with the upload.
Therefore, what I am thinking about is:
- client (javascript running in browser) generate a random symmetric key, encrypt the file and upload it to GCE
- client send the key to the server and destroy it
Communication between client & servers is of course over https.
Is this approach secure? If not, why?
So you’re encrypting a file to upload to a third party service, then sending the key to your own server.
Let’s take a look at your proposed options for sending the key:
- Send it over TLS
- Encrypt it with your server’s public key, then send it over TLS
So what you want to know is if option 2 is better than option 1.
Can TLS be bypassed?
If an attacker can’t get past TLS then both options are fine, so let’s assume they can (eg sslstrip, using social engineering to get you to trust their TLS certificate, etc). If the attacker can get past TLS, that sucks. How much that sucks depends on the type of attacker.
Passive attacker
If a passive attacker can read your TLS traffic, they’ve undermined the confidentiality, but they’re unable to alter the traffic in any way. In this case, using assymetric encryption to encrypt the file key before sending it to your server would protect it.
Active attacker
An active attacker can read your traffic, but they can also modify it. In this case, you’re hosed. They can simply alter the JavaScript to have the client upload the file to their own server before encrypting it, and perhaps still encrypt it and upload it to the third party service so no one notices anything wrong.
Which is more likely?
If someone is in a position to read your TLS traffic, they must either have your certificate’s private key (which is very bad), or they’ve intercepted the key exchange, which means they’re probably an active attacker.
Is there a better option?
If you’re worried about the safety of your TLS connection, the solutions are HPKP and HSTS (although beware of caveats).
Conclusion
In a web context, trying to use JavaScript to improve the security of your connection is generally doomed to fail. Do as much as you can to make sure your TLS connection is secure and just use that.