Hacker News new | ask | show | jobs
by colinsidoti 4711 days ago
I've looked into this before and concluded it was possible, although I forget exactly how.

I bookmarked https://crypton.io/ and http://peerjs.com/ . PeerJS is p2p WebRTC, which I believe I chose because I wanted to do secure, real-time p2p file sharing.

That isn't 100% relevant for this, but downloading the file over some socket into client-memory then decoding it there sounds like something webrtc could be a good option for.

Crypton handles the crypto.

I think the biggest thing someone who tackles this needs to realize is that perfecting the crypto doesn't matter 100%. If you could get something working that's doing some kind of encryption/decryption without exposing anything to the server, crypto experts will come in and help secure everything (see: mega)

Edit: I should mention that I didn't research this extensively, and better libraries might be (and probably are) available.

1 comments

It's a really interesting idea (and sounds really fun to build) but a bad idea from a security perspective. Javascript crypto in the browser just doesn't make sense[1].

Summary of the link: Since you trust the server to serve the JS files, you might as well trust it to do the decryption and present it all over SSL.

> I think the biggest thing someone who tackles this needs to realize is that perfecting the crypto doesn't matter 100%. If you could get something working that's doing some kind of encryption/decryption without exposing anything to the server, crypto experts will come in and help secure everything (see: mega)

This is an especially bad idea. Application that perform crypto should be designed properly from the start. It's not something you can just patch on later. Building crypto programs to learn/test/explore is fine but building a product for actual usage and then expecting others to fix it after the fact is a terrible approach.

[1]: http://www.matasano.com/articles/javascript-cryptography/

Err I don't think this would stop me. But let me preface this by saying I learn something new about security quite frequently, so if there's a major premise I'm missing, I am both interested in learning about it and not completely surprised.

The main issue here is that your Javascript can potentially be owned by XSS or other approaches. If you own the javascript, you can send plaintext passwords or keys (which should have only been available to the client) back up to some server.

Even with that possibility though, I still think using browser-based crypto creates a more secure environment than the server storing unencrypted files. The author makes a good point in saying that you download javascript on each request, which makes it more susceptible to getting owned than a native-app, but I think a successful attack with this approach will still be an order of magnitude less severe than if an attacker owned a server full of unencrypted data. If the data is unencrypted, an attacker that manages to own the server has access to everyone's data. With it encrypted, the attacker will only get data from users who are using the site while it's owned.

Isn't that still a better option?

> Err I don't think this would stop me.

On the contrary go right ahead. Learning through doing is the way to go. I'm just saying there's a big difference between testing/learning/prototyping and releasing something that is claimed to be secure. Otherwise you end up with Cryptocat[1].

> Even with that possibility though, I still think using browser-based crypto creates a more secure environment than the server storing unencrypted files.

If you're using any JS then you have to completely trust the server that is serving it. At any point the server could replace "good.js" with "bad.js" and the browser will happily execute it. Any encryption you perform on the client side would be moot as "bad.js" could do whatever it wants with your plaintext and your encryption keys.

> If the data is unencrypted, an attacker that manages to own the server has access to everyone's data. With it encrypted, the attacker will only get data from users who are using the site while it's owned.

Again you're trusting the server to not save your encryption keys though by serving you "good.js" and not "bad.js"! All roads lead back to you trusting the server to play nice.

Unless you use untrusted remote services as opaque object stores and handle all encryption via secure code on the client side with proper signatures to prevent remote tampering[2], you're trusting the server not to compromise you.

[1]: http://en.wikipedia.org/wiki/Cryptocat#Security_concerns

[2]: Tarsnap (https://www.tarsnap.com/) is a perfect example of a client not trusting the server. The tarsnap service stores it's data on S3 but first all data is encrypted client side on your own machine. From the tarsnap service's perspective it's just storing a bunch of random binary blobs and that's all your client sends/recieves. Encryption/decryption happens locally on your machine.

Additionally, it is almost impossible to verify the security of a system that uses encryption via javascript in the browser. The algorithms aren't that hard to verify, but making sure that keys are handled securely, and that you don't open yourself to timing and side channel attacks is really hard with such a big stack of things competing for scheduling, managing memory etc.

So there are two problems:

1) You get code from the server and execute it -- it might not be the code you think it -- it might not be the code you got yesterday (and there might be third party code injected, if there is an XSS vector -- or you know, your browser doesn't check to see if the servers ssl certificate has been revoked...).

2) Even if you run the code locally (say distribute it as html+js+css "app" in a zip file signed with gpg) -- it is still running on top of a pretty rickity rack of technologies, your javascript vm, the browser dom, a mess of ui toolkits and c/c++ routines that manage memory -- and has been seen again, and again -- it is really hard to actually implement crypto in such a way that there are no side channel attacks, no timing attacks and no information leaks.

Essentially 1) running random code isn't secure, and 2) implementing good crypto is hard. Really hard.

The only real solution is to get a good crypto-api into html5/browsers, but even then things aren't "safe". Say you could:

    plaintext = api.crypto.decrypt(AES-256-CBC, \
                  ciphertext, key)
Now, what happens with plaintext? Is it written to swap? Cahces? If you use that to show an image in the browser, is the image cached along with other files?