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.
This is true. However, you can say the same thing about, for example, retrieving an ISO of Ubuntu. A cryptosystem is as weak as its weakest link, and that weakest link may of course be the way you downloaded the cryptosystem in the first place.
But once the cryptosystem is in place, you don't have to trust SSL any more. By default, webapps are always retrieved from the server for every new session, but application manifests and offline storage are an effective means of avoiding this. You can build a webapp that is only ever downloaded once, and from then on loads its own code from the filesystem; and which verifies new "releases" of its own source using whatever crypto it likes before overwriting the client-side stored copies of itself.
Neither Lavabit nor Hushmail implemented this sort of application-release policy, but they easily could have.
Obviously, you cannot simply assume that an ISO you download off the Internet is secure. That's a problem that's been well known since the mid-1990s, when projects began publishing hashes and PGP signatures of their binaries, widely, so that a discrepancy between what you saw and what someone else saw would stand a good change of being noticed.
The problem with booting up crypto in a browser is that it forces you to do that kind of checking on every page load, often at sub-second rates. And not only that, but it complicates the trust evaluation by making it just about as hard as possible to figure out all the components that you actually need to evaluate.
But if you don't trust Hushmail they could force a back-doored update onto you.
Challenge: I have a client (web browser) and I have a back-end server (sitting deep behind several layers of intermediate servers of varying degrees of trust) and these two entities need to exchange some sensitive piece of information (a credit card number, etc). How do I transmit this information (either from client to server or the reverse)?
Problems/Assumptions: Let's assume I trust the front end server explicitly to serve fully server-controlled data. Obviously, if we don't trust the server serving me the JS it is all for not. Now, let us also assume that, although my front end server is trusted, it, as well as all of the intermediate servers may accidentally log data that flows through them. In other words, we assume that if I pass a plaintext credit card number over a trusted SSL connection to the server, it, or any of the intermediate servers on the path to the trusted back end server, may accidentally log the sensitive data. How do you solve that problem?
Solution: You could use client-side crypto to create an end-to-end channel that transmits the sensitive data to the back end server.
So, yes, the above solution assumes a fully trusted front end server. In this case, the client side crypto is more to protect the service provider than for the user, but it does seem to provide some sort of "existence proof" in so far as it is a problem that exists in the real world, is made better using client-side crypto, and doesn't seem to have many alternative solutions that provides the same assurances.
P.S. This is more or less what BrainTree does with their client-side encryption for credit card processing (https://www.braintreepayments.com/braintrust/client-side-enc...). In this case, the front end server needs to be trusted, as it is serving up the public key to bootstrap the whole system. But, if we assume the server is trusted (even without client-side crypto we have to assume this for any security) then this approach mitigates the problem of logging credit card data by accident.
Now, maybe this use case is the only legit use of client-side crypto. But, it does make me take pause before dismissing the approach entirely.
I think you are unfairly reframing it as some sort of debate. It's like not being totally decided on if you should log into your server over telnet from a coffee shop. Even if you don't see the weakness, attackers do.
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.
This isn't a new idea that we're shooting down before it has a chance to fully form. It's something that people have been trying, and making dangerous security claims about, for at least 10 years.
It's possible that the core issues are resolvable, but they would likely require substantial changes to the way the web browser works. Whenever people start thinking about a way to make a mechanism like this work correctly, the scope of what's required unravels quickly. At this point, I don't know of any defined or even partially articulated proposal that makes sense and accounts for the bulk of the gotchas.
Given that we haven't even been able to get correctly-scopable cookies yet (something the vast majority of the web wants and which has been clearly defined and articulated for many years), I'm not sure that we should hold our breath for this.
Since code can be executed by almost every resource on a webpage, basically the entire would have to be stored on that separate third party website, the html, the css, maybe throw in the images too given their history of weird exploits.
Not saying that's a very crazy idea, but I'm saying it's way beyond the scope of these opal guys, and probably not what most people 'working out' browser crypto are after.
Don't the same problems apply to any autoupdating system (including smartphones, tablets and computers)?
I've posted once before asking that Chrome and Firefox implement certificate pinning APIs for extensions/addons so that MITM SSL attacks can be detected. Maybe they'll see it now. :)
Opal requires as little trust as possible, but you are correct that some server-trust is required at the moment.
I hope that apps like Opal will encourage more progress on browser/javascript cryptography. The W3C crypto spec is coming along nicely, and things like Content Security Policy address some of the concerns about delivering secure javascript.
One nice thing about web-apps is that they are by-default open source, and browsers are bundled with all sorts of diagnostic tools. Anybody who worries that their data is being "sprayed" can just open the network tab and see exactly what is being sent over the wire. Obviously we don't expect many users to do this, but it's one way to enforce our honesty until better solutions exist.
Unless there is some other mechanism at play here, it requires full server trust.
> I hope that apps like Opal will encourage more progress on browser/javascript cryptography. The W3C crypto spec is coming along nicely, and things like Content Security Policy address some of the concerns about delivering secure javascript.
I don't think you can just cross your fingers and hope for the best here. Whether or not it's coming along nicely is debatable, but one way or another the W3C crypto API has no bearing at all on this problem.
You're talking about implementing a "secure" service using a mechanism that is known to be insecure. For a mechanism like this to function correctly, it would likely require substantial changes to the way the web browser works that aren't currently on anyone's roadmap.
Again, this is not a theoretical problem. Two companies have done the exact same handwaving that you are doing now about users watching tcpdump to verify their traffic, and both of them were functionally destroyed when that handwaving didn't work. It doesn't seem prudent to knowingly put users (or yourselves!) into that position again.
Meanwhile: the network tab thing only does anything if you do it every time and validate all the content. Nobody does this, ever.
On top of that we would need some code delivery system with built-in trust verification. This way you could load an up to date copy of PGP written in JS and verify that this code comes from a source you trust.
Then again, this is starting to look a lot like a secure package management system and downloaded software vs the continuously updated web apps we have today, so it might not be worth reinventing the wheel...
You could talk about ways to independently sign and verify some crypto primitive or crypto library and be confident that it was being used to encrypt your communications appropriately. But this wouldn't help at all. There's nothing stopping the person controlling the server (or MITMing your connection to it) from adding additional code that scrapes the text input boxes, or captures keystrokes, or simply follows the appropriate variables down to the ones which contain your text before its sent off, and then sending that back to the server in an XMLHTTPRequest, via a websocket, via loading an appropriate image, or even hiding it quite well among the timing of when requests are made to the server.
The fundamental problem is that the code comes from the same person providing you the connection, and it is updated every time you use the page, so it offers no additional security above just trusting them directly.
If you want good crypto and good security, you want stable client side software from a trusted source, and a different source routing your traffic, so that both of them would have to be compromised to compromise your data.
Now, there may be one small advantage in client-side crypto. That's if due to problems with TLS (in particular, the version and protocols supported by your browser), there are TLS weaknesses that can be exploited, like a MITM attacker forcibly downgrading your crypto to a weak algorithm that allows them to eavesdrop but not forge content. In this case, stronger crypto implemented in JavaScript could be used to keep your data confidential. But this is a very narrow corner case, that's probably better handled by fixing browsers so they aren't prone to protocol downgrading attacks.
In fact this is a pretty insidious mistake since you think you are doing the right thing by using a high-quality library.
http://trypepperjs.appspot.com/
https://github.com/google/pepper.js
(note the `google` in the link).
It's terribly confusing, especially since this article talks about both :)
I completely agree that further analysis is needed on js-nacl, but I hadn't considered that compiler optimizations might lead to vulnerabilities.
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.
Even on the LLVM side certain optimizations may be dangerous in crypto code. I wouldn't play with optimization settings unless I was sure I knew what I was doing. And I'd still think twice.
http://en.wikipedia.org/wiki/Network_Security_Services
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.
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.
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.
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.
2. https://github.com/rogerwang/node-webkit
5. http://nodejs.org/api/crypto.html
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.
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).
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... 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.
You can read more here: 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.