3 ms·
"If the server is compromised [insert disastrous result here]" applies more so to many other servers serving you crypto - I feel there's the advantage of being
by magikarp 15y ago
"If the server is compromised [insert disastrous result here]" applies more so to many other servers serving you crypto - I feel there's the advantage of being able to verify the .js files yourself in your browser here:
<!-- cryptocat uses the crypto-js library - http://code.google.com/p/crypto-js/ http://code.google.com/p/crypto-js/ -->
<!-- http://crypto-js.googlecode.com/files/2.3.0-crypto-sha1-hmac-pbkdf2-blockmodes-aes.js http://crypto-js.googlecode.com/files/2.3.0-crypto-sha1-hmac... -->
<script type="text/javascript" src="js/crypto.js"></script>
- tptacek 15y agoYou can't just verify the .js file! You have to verify every line of JS code that ever hits the JS interpreter, whether it's specified directly in the source code that the author told you about or eval'd later in some random event handler. That code could come from an explicit <script> tag in the original DOM source; it could come from an event handler specified in the DOM, or set later by any other piece of JS; it could come from an Ajax request handler; in many browsers, it can even come from CSS. It can easily hide itself after it does its job, and it isn't going to look like "<!-- zero out AES key here -->". The browser JS runtime does not provide the tools you need to verify the integrity of a cryptosystem. Full stop. Actually, browser JS runtimes don't even provide the tools you need to safely run a cryptosystem. How do you know what intermediate values are cached by any given JS? How do you know if any given crypto function is leaving footprints in browser memory? You don't; nobody does; nobody has published the exhaustive analysis of any browser JS to support an argument either way. Not that that matters for crypto.cat; they don't seem to care much about side channel stuff; for instance, their HMAC compare is the JS string "!=" operator. As for "applies to so many other servers": I don't know what you're saying. You made a claim about the security properties of this application. That claim was wrong. It doesn't become right when you point out some other app that has the same flaw.
- deno 15y agoWhat about loading Java applet (and communicating from JS) that handles all encrypting/decrypting? Would that take care of at least the latter concern?
- tptacek 15y agoYes; you could just use Bouncycastle's Java PGP implementation, which is probably the safest option. But people hate Java, and it's increasingly disabled in browsers.
- deno 15y agoWell I thought the question was interesting because if that'd work, so would a native Web API.
- tptacek 15y agoA native web API would work! I think it'd be great if everyone could agree on some basic, high-level crypto functions, implemented in browser C, to expose to JS. You'd want the interface to look much more like Keyczar than crypto-js, though.
- deno 15y agoI was also wondering — I hope you don't mind — would it be considered safe to just verify signed messages using cryptojs? For example, let's say the environment (webapp) is bootstrapped using TLS, this includes the public key. Now could this application receive signed messages through different, unsecure channel and verify them safely using the public key received through the secure channel?
- tptacek 15y agoIf it can be safe to verify the integrity of a JS cryptosystem at all, I think it's going to turn out to be tricky to do it. Like I said elsewhere on this thread, the number of ways a web page can influence the Javascript runtime is huge, and a lot of those ways are cached.
- deno 15y agoWell the integrity of the JS cryptosystem would be no worse than the integrity of the webapp itself. I understand that one cannot trust the JS crypto for handling the private key and doing any singing & encryption because of the possibility of leaking information through side channels. That's why I was wondering if it'd be possible to use JS crypto in only one way — that is to verify messages against public key received through the secure channel. If the JS crypto only does verification, it wouldn't matter if the _public_ key is cached, as long as it can't be arbitrarily changed by another process. If the server is taken over or there's an XSS or other client-side vulnerability the bidirectional TLS would be similarly useless anyway.