
Cryptography in the Browser - thedaniel
http://blog.opal.io/crypto-in-the-browser.html
======
moxie
Client side cryptography is almost always about providing a solution that
doesn't require server trust. This article mentions end-to-end encrypted
messaging, for instance, which provides the nice property that not even the
messaging server can read the message contents.

The problem with webapp-based javascript cryptography is that if the crypto
code is delivered by the server, then the client is back to trusting the
server. The server operator, an attacker who can compromise the server, or an
attacker who can compromise the SSL connection from the browser to the server
can modify the JS to spray plaintext wherever they'd like.

Basically, the JS crypto is reducible to the strength of the SSL connection.
Anyone on the other end of the SSL connection, or anyone who can break the SSL
connection, can get your plaintext. This makes the JS crypto nothing but
overhead. It's just hand-waving at that point.

This is not a theoretical weakness. This is exactly happened to both Lavabit
and Hushmail. The experiment has been tried and the hand waving didn't amount
to much. There's no need (and no excuse!) to try it again.

~~~
cortesoft
While these known issues are true, and still need to be worked out, I don't
think stopping all work on crypto in the browser is the best course of action.

There are technical ways we could mitigate these vulnerabilities (signing of
JS downloaded from a site, for example). Maybe having crypto in the browser
become a thing is the way that these features get the support to be
implemented.

~~~
nwh
It always comes down to this; would you prefer security, or just something
that makes you feel fuzzy? Crypto in JavaScript only gives the latter.

~~~
nlacasse
I disagree. Javascript cryptography can provide real security, it's just
important to keep in mind what is being secured, and where the vulnerabilities
are. Currently, js crypto is vulnerable in that its difficult to verify that
the js a browser is running is the intented code.

Every day, millions of people are sending sensitive data over very insecure
channels like email and DropBox because secure tools like PGP are to difficult
for them or their friends to use. Clearly some security is better than none,
as long as the limitations are known.

~~~
tptacek
This is like saying a sign that says "attackers keep out" provides real
security, as long as you keep in mind that it only works if attackers obey the
sign. After all, Dropbox doesn't have an "attackers keep out" sign!

~~~
azakai
No, it's more like an imperfect lock is still more security than no lock at
all on your door.

~~~
DanBC
No, it's more like people thinking they have a high grade lock on their door,
when in fact they have a broken lock. They can't see it's broken, but anyone
who knows about locks knows it's broken, and how to bypass it with a bobby
pin.

~~~
eldondev
Is this supposed to be serious, because we want javascript to be better, or
sarcastic, because most people DO live behind locks that are broken and can be
bypassed trivially with relatively unsophisticated tools? Everybody break out
your bobby pins!

~~~
nwh
You would have extreme trouble picking a lock with a bobby pin, they're much
too fat to do anything outside of a movie.

------
tinco
Please stop upvoting this article, it's misleading at best. It links to the
article everyone should read on browser cryptography, the article that says
exactly why browser cryptography does not and basically never could work.

The article then picks the least important of all security problems, that
there isn't (wasn't) a secure way of generating random numbers, acts as if
that was an important point and then carries on as if browser cryptography has
been solved.

In their about page they claim: "As a result, Opal is able to guarantee that
the only people who are able to read a secret file are the sender and
recipients."

This is plainly not true. The people who are able to read these secret files
are always those who control the browser. They might claim that they're able
to guarantee it because they control the code that is sent by the server, but
recent history has shown us that if they were to be forced to break that
guarantee, they would not be allowed to let anyone know.

So what is their guarantee worth to anyone? Jack shit.

~~~
tptacek
Part of the problem is that the JS crypto article they linked to isn't very
good, but has for some reason become emblematic of the whole argument against
JS crypto. It deserves an update.

------
foobarqux
Compiling nacl to javascript is probably a very bad idea without some further
analysis. There are almost certainly specialized code constructs that will be
lost in the transformation, like branchless code paths, that are designed to
prevent certain types of attacks.

In fact this is a pretty insidious mistake since you think you are doing the
right thing by using a high-quality library.

~~~
nlacasse
Emscripten compiles the input source with LLVM, then converts the LLVM
bytecode to JS. Most of the optimization passes are done by the LLVM compiler.
Are you suggesting that LLVM (or optimizing compilers in general) should not
be used to compile crypto libraries?

I completely agree that further analysis is needed on js-nacl, but I hadn't
considered that compiler optimizations might lead to vulnerabilities.

~~~
tptacek
That's might be a sign you don't pay enough attention cryptographic research;
compiler optimization side channels are not news.

Of course, the notion that the _compiler_ is a threat here is getting a bit
ahead of ourselves, because you don't even know what side channels are in the
_runtime_.

------
rosser
The Chicken-Egg problem is Problem 0 with Javascript crypto. Until you can
solve that, everything else is just farting into the wind.

~~~
jxson
Progressive enhancement is a real thing and as the browsers start to implement
native support for the rest of Web Cryptography API the situation will only
improve. We have to start somewhere.

~~~
wmf
Assuming that browsers have implemented Web Crypto, how do you know you're
using it and not an evil polyfill?

~~~
blazingice
Some JS engines already disallow security-violating operations from happening
(such as inserting evil hooks into document.location). These same protections
could apply to any Crypto object.

------
eliteraspberrie
_Moreover, the LLVM compiler can perform many optimizations during
compilation, so the resulting JavaScript is highly optimized._

Optimization may actually be an argument _against_ C-to-Javascript translated
cryptography.

NaCl was written in C, according to the constraints and degrees of freedom of
a standard C compiler -- which are not the same as those of an interpreted or
JiT compiled language.

I am not a cryptographer, but source-to-source translation of cryptography is
looking for trouble.

------
napoleond
Say it with me: _browser crypto is bad_. But if everyone really wants to build
crypto apps using front-end skillsets (which I can understand, because I've
done it[0]), go for it! Who says you need a browser? Use Phonegap[1], or node-
webkit[2], or appjs[3], or TideSDK[4] (well, not Tide, unless you're a
masochist). If you don't want/can't use Node's crypto stuff[5], use SJCL[6] or
OpenPGP.js[7] (the last two are _not_ battle-proof libraries, though, because
_browser crypto is bad_ so few serious cryptographers have bothered to review
them... hopefully that will change if enough people use them outside of the
browser). Voila! The convenience of the tools you know, and automatic cross-
platform access, without the badness of browser crypto.

0\. [https://parley.co](https://parley.co)

1\. [http://phonegap.com/](http://phonegap.com/)

2\. [https://github.com/rogerwang/node-
webkit](https://github.com/rogerwang/node-webkit)

3\. [http://appjs.com/](http://appjs.com/)

4\. [http://www.tidesdk.org/](http://www.tidesdk.org/)

5\. [http://nodejs.org/api/crypto.html](http://nodejs.org/api/crypto.html)

6\. [http://crypto.stanford.edu/sjcl/](http://crypto.stanford.edu/sjcl/)

7\. [http://openpgpjs.org/](http://openpgpjs.org/)

------
dyoder
The negative response to this post is over the top.

At most, you can say that they overstated their case by neglecting to talk
about server trust and using the word "comfortable" in an article about
security. :)

To address a few red herrings:

Saying that no solution is better than a flawed solution is absurd. There's no
such thing as impenetrable security. On that basis, we shouldn't bother with
HTTPS. For that matter, we shouldn't bother with passwords, either.

We do these things because they make attacks incrementally more difficult and
thus redirect attackers' efforts to more vulnerable targets, or make it
expensive enough not to bother. Every little bit helps.

Saying that you can't do this because you have to verify everything on every
page load utterly ignores the past decade of development of rich client
applications.

Saying that you shouldn't do this because it's been tried before also ignores
virtually the entire history of technological innovation.

This is important problem and constructive criticism from security experts is
extremely valuable. But the only "sophistry" I'm seeing here is from the
people who can help the most.

This is a beta, invite-only app bootstrapped out of the proverbial garage.
Their blog post on the technical details missed a few things. If you've ever
been in those shoes, you know how easy that is to do. I've seen billion dollar
companies do worse. Most of the article was accurate, well-written, and
probably helpful to a lot of readers.

Help 'em out, don't tear 'em down.

------
zentrus
Having the crypto code delivered by the server to provide real-time "end-to-
end" security is surely a problem. But, I believe there is a specific use case
where even not-so-perfect javascript crypto increases security in a
significant way. Imagine you have a system where you want to send encrypted
files _that are stored on the server_ to be downloaded later by other users.
With javascript public key crypto a la PGP, the user could encrypt this file
using keys stored locally. These keys are "uploaded" to the web page when they
are needed but not actually sent to the server. The cipher text only is then
uploaded to the server and stored. Recipient users can then download the file
and decrypt in a similar manner.

So what does this help protect against? You are mitigating the situation where
the server becomes compromised. In the event your server is compromised, any
previously encrypted files are protected _as long as the keys are not used
again_ after compromise (since malicious javascript could be delivered to
obtain the key).

------
bitexploder
Came to this thread knowing tptacek would be here, discussing what a terrible
idea this was. Got moxie and tptacek. Was not disappointed.

This is effectively a me too, but as someone who has spent considerable time
researching, understanding, and explaining this problem to customers, let me
just say it is a very dangerous thing to do (try to implement a "secure"
system on top of JS Crypto in the browser). Moxie and Tom are completely
correct and I cringe every time I see one of these projects.

And if you aren't convinced after reading this thread:
[http://rdist.root.org/2010/11/29/final-post-on-javascript-
cr...](http://rdist.root.org/2010/11/29/final-post-on-javascript-crypto/)
start here. He covers the topic exhaustively. I feel like anyone arguing about
if this is a good idea should do some research and come to the discussion
informed. Nate wrote this article over 2.5 years ago.

------
peterwwillis
All browsers already have crypto. Why the fuck are people trying to invent
their own when it's built in?

[http://en.wikipedia.org/wiki/Network_Security_Services](http://en.wikipedia.org/wiki/Network_Security_Services)

[https://developer.mozilla.org/en-
US/docs/Mozilla_Crypto_FAQ](https://developer.mozilla.org/en-
US/docs/Mozilla_Crypto_FAQ)

All you need is some kind of new "Web Standard" glue between the browser and
the JS and do whatever you feel like using the native crypto functionality of
the browser. You don't need to add more layers of complexity. But you can add
a small bit of abstraction to what is already there.

~~~
tptacek
How exactly do you think having built-in AES primitives solves a problem for
browser crypto? Content-controlled Javascript still controls how those
primitives are used.

~~~
peterwwillis
First, not all JS delivery is subject to MITM. Having the ability for JS to
use built-in, fast, reliable crypto code is useful in many cases. And it's
going to be more reliable, and faster, and just better working in all cases by
using what's in the browser VS someone's bleeding-edge library based on some
other library based on etc etc.

Second, when we get down to it, if you can't trust your content, you can't
trust your content. Do you second guess the crypto on your laptop because you
might be subject to evil maid or other physical attacks? No, because there is
some inherent trust, just like the people who do online banking and shopping.
The integrity of the content is important, but not the only issue, and
arguably not the highest priority.

Third, what we use the crypto for is completely subjective. Maybe someone
using it doesn't care about the integrity of the instructions delivered; it
depends on the case. You can't use one case as a yardstick for all of them.

People obviously want to do crypto from JS. I'm not proposing a solution for
all the potential problems therein. But if you're going to do it, do it right
and use the native code that _already is there_.

------
yeleti
We implemented a system where the key used to encrypt messages is generated in
the browser and never leaves the browser. This ensures even we cant decrypt
messages. The downside is the end user has to remember a 'Room Secret Key'.

You can read more here:
[https://www.tesla.im/#encrypted_rooms](https://www.tesla.im/#encrypted_rooms)

We are just a few weeks into beta and have only a few hundred users. Been
working well so far. However it's too early for us to give solid validations.

------
expaand
It sounds like Lastpass is a goner, then.

