End to end encryption in JS Web Apps
2 min read

End to end encryption in JS Web Apps

The most significant burden to mainstream encryption is the proliferation of web apps, such as email clients, and the lack of a good encryption story inside the browser. The question is: can we use end to end encryption inside JavaScript web apps?

Asymmetric encryption suffers from the same problems as OpenID, it's a complex subject and if its success is conditional on being understood by your average user then it will never be popular in the mainstream. The only way to deal with crypto is to do what we programmers do best: abstract it and make it work transparently behind the scenes.

The issue is with 'The Cloud'. A lot of communication applications, perhaps the majority of them, are served and hosted remotely. So how can we add encryption to hosted web apps? We need to solve three problems:

  1. Asymmetric (RSA) encryption/decryption routines in the browser
  2. Public key discovery
  3. Secure private key distribution amongst a users' devices

For JavaScript encryption/decryption routines we have a spec called WebCrypto. Both Google and Mozilla are working on this, but the bad news is it isn't available in any browser today [1]. A draft of the spec was just published though, and both browsers have open bugs showing active development. Hopefully implementation is only a matter of time [2].

Now, the browser isn't a trusted client - that's true. A company could just update their JavaScript and log data whenever it's decrypted on the client-side. Indeed, they might be compelled to do so. However, the key thing is that this can be detected. Knowing your communications are compromised is half the battle.

There are a few ways that public key discovery could be implemented. For example, this could be part of the JS web app - the first time the user signs up their public key (stored in the browser's keychain) is requested and stored. Indeed WebCrypto contains provisions for generating & retrieving keys.

Again, this is open to abuse - a malicious service provide could MITM communications by inserting their own public key. However, like the previous attack this ultimately could be detected (not least by key pinning).

The last issue is private key distribution. Your average user wants apps to work seamlessly between their devices without them having to manually copy over private keys. In addition syncing private keys with an external provider, such as Apple, clearly isn't secure. How do we provide an easy key distribution system?

To be honest, I don't have a good answer here. Perhaps secure synchronization on the local network similar to the way OSX's AirDrop works? Or perhaps we should just encrypt and duplicate each message multiple times for all the recipient's devices?

Security is always a trade-off with convenience, and the solutions I've presented above clearly have their own compromises. Indeed, as well as the security concessions I listed above, there are also convenience ones too. For example, without the plain text of a message web apps can't offer search. However, surely these compromises are better then the situation we're in now - no security at all.


[1] - You can tinker with a Polyfill for now
[2] - Although it won't hurt to voice your support, or even give a hand implementing it.

Email: alex@alexmaccaw.com
Key ID: CBB1BD61
Public key: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xAF618363CBB1BD61

Enjoying these posts? Subscribe for more