January 23, 2013

Web Browser Cryptography is a Good Thing

Recently I have seen a lot of security experts objecting to the use of Javascript in the browser for cryptography. Most of these objections have been raised in response to the release of two websites that implement their cryptography in Javascript: Nadim Kobeissi's Cryptocat and Kim Dotcom's Mega. In response to the objections, I give a very high-level description of a code signing system that could make it safe to do cryptography in Javascript, and argue that we should start working at making web browser cryptography secure.

Objections to Web Browser Cryptography

The objections fall into three categories, which I will address individually.

  1. The security of a website that does cryptography in Javascript depends on the security of SSL.

    This is currently the case. If an attacker can break SSL, they can modify the Javascript code as it's being sent to the browser and insert some bit of code that leaks all of the cryptographic keys. We have good reasons to doubt the security of SSL, too. The recent Certificate Authority (CA) breaches (DigiNotar, etc.), and the general idea that hundreds of CAs, in countries all around the world, have the power to intercept our SSL connections, are all good reasons to avoid depending on the security of SSL.

    It's important to note that it's SSL's PKI—the entities we've chosen to trust—that we have problems with, not the SSL protocol itself (although there have been some problems with that too). Therefore, to make Javascript cryptography secure we have to provide code integrity checking without relying on the SSL PKI.

    One approach to removing the dependency on SSL's PKI would be to develop a code signing infrastructure for the web. Such an infrastructure would not only be useful for integrity checking cryptography code, but could be used to mitigate XSS attacks. It doesn't need to be very complicated, either. A browser add-on containing the web site owner's public key could verify a signature attached to the code before allowing it to execute. The problem of distributing the web site owner's public key remains, but the code signing keys would be expected to have long lives, so users would have good reason to be very suspicious when the public key changes (unlike SSL). A Trust On First Use (TOFU) model, through SSL, is probably sufficient. Or maybe the keys can be distributed through DNSSEC.

    Such a system would be very simple and easy to implement for different browsers. It could even be standardized and built directly into our browsers or the HTTP protocol. At the very least, it would be more efficient than moving all of the application's client-side logic into a browser extension that has to be maintained for many different browsers (which is what happened to Cryptocat in response to criticism).

  2. You have to trust the machines serving the Javascript code.

    This is also currently the case. But if we suppose the code signing system mentioned above exists and is used, the problem becomes, "You have to trust the people (and machines) who can sign the code." Assuming we've acquired the web site owner's public key securely, then this just says we have to trust the web site owner to not sign malicious code and to keep their private key secret. Now we're no worse off than we are for normal software:

    • Windows users have to trust Microsoft to not include malicious code and to ensure no one else can modify the Windows source code.

    • Firefox users have to trust Mozilla to not let any malicious changes into the Firefox source code.

    • And so on...

  3. Javascript is missing important cryptographic primitives.

    There's a Web Cryptography Standard on the way, but current browsers are lacking essential cryptographic primitives. Most notable is the lack of cryptographically secure random number generator and efficient (native) implementation of key stretching algorithms like PBKDF2. Obviously if we want to do cryptography in the browser, our browsers will have to start providing these things.

Advantages of Web Browser Cryptography

We get some significant advantages by implementing a code signing system and doing cryptography in Javascript:


Being able to do cryptography in the browser opens up a whole new universe of web applications. We can create web sites that know nothing about their users, and we can get people to use cryptography without forcing them to download strange and barely-usable software. The advantages are too great to ignore. Therefore, I suggest that instead of bashing those who try to write cryptography applications for the web browser, we should work together to make web browser cryptography secure.