From the two quick reads I've given it, not a fan.
On the plus side: building this stuff directly into the browser image may prevent people from deploying Javascript Cryptography, which is unsafe in every environment. Systems built on the Web Cryptography bindings are at least anchored to trusted implementations of algorithms already resident in the browser.
On the minus side:
* These interfaces may have the opposite effect. Mass-market websites must support all popular browser versions. For the foreseeable future, we won't have a market in which the majority of browsers implement something like this. Unfortunately, the web crypto API is something that is very easy to duplicated "cosmetically" in Javascript. So the net effect of this in the medium term is probably negative. That said, I also understand that we've got to rip off the band-aid sometime.
* The interface is low-level. I appreciate that an API like this naturally wants to be low-level, to maximize the number of things you can build on top of it. But most of the things you could build on these particular building blocks will have subtle vulnerabilities. Not only that, but the interface doesn't appear to provide even the "envelope" abstraction that other low-level libraries present.
* So much of this design is low-level that enough of the security of the system is left to content-controlled Javascript, so many (perhaps most) of the systems that rely on this library are going to have exactly the same problem as they do now.
* The low-level building blocks they provide are incoherent. If you wanted to just expose all the little knobs and wires that it could take to implement pre-existing (and broken) crypto standards, then an interface which pretends that AES-CBC and AES-GCM are two different ways to do the same thing makes some sense; some systems need GCM, and some need CBC, and you don't have to give much thought to the difference. But this library doesn't even do that; for instance, it doesn't look like callers control the nonce in AES-CTR. A good way to sum this up: if this API succeeds in the market, there are going to be deployed, widely used systems that use RSA for bulk encryption.
If I was elected Archduke of Browser Crypto, the first standard I would propose would be a simple authenticated AES-encrypted envelope format; something like, PBKFD2-keyed HMAC-SHA256-authenticated AES-CBC messages. Something impossible to screw up, because Javascript authors aren't asked to make design decisions.
I believe you are suggesting that we make a more foolproof API like keyczar. The original idea of DOMCrypt was along those lines as well. I don't think we will be able to avoid specifying and shipping the low-level API at this point. It would be nice to define such a foolproof API on top of the low-level API, prototype it with a JS implementation, get feedback on how useful it is (i.e. whether it is too limited for the use cases people have), and then push browser makers to provide this safer API natively. I think the main concern with a keyczar-like API is that we won't be able to create one that significant numbers of websites would actually use.
We've discussed much of this before on HN, and I am slowly but surely starting to see exactly what you mean. Getting everything in crypto just right is a hard problem, especially with the disparity between different crypto providers and how it should be implemented to be secure.
The biggest issue I have is that unless low level primitives are available it is hard to work together with various other libraries/standards. Getting Java and OpenSSL based crypto to play nice is already harder than it should be, I can't imagine what a mess it would be to try to make it work with yet another standard. And at the same time if those low-level primitives are available people are going to use them instead of the higher-level functions because they have certain specific requirements.
---
Any specific reason as to why AES-CBC? If seeking is required wouldn't AES-CTR be a better choice? Or are you making assumptions that the payload size is small enough that decryption of the whole object is feasible?
Totally agreed on every level. If you want to add security, you do it from the high level; exposing low-level building blocks is a recipe for disaster.
While I think this could be a good thing in theory, exposing such a low level crypto interface is likely to end in pain. How many people can combine the building blocks into something secure? And MITM/XSS still give up the keys to the castle.
I'd much rather see a simple high-level interface to crypto in the browser.
The plan is to first nail down this low-level API, and then specify a high-level interface wrapping the low-level one that makes it much easier for most developers to get things right.
This looks like it could be pretty useful. The main argument against crypto in the browser is that if you send crypto js over a non encrypted channel it's vulnerable to MITM, and if you're going over HTTPS you might as well just send it plaintext. If the browsers themselves implemented secure crypto it could be a boon to certain types of applications, for example S/MIME in webmail.
I don't see this adequately defending against MITMs or XSS. You can still hook all the crypto primitives, inject new keys, or pull out existing keys from the same origin.
This scares me; a lot of people are going to assume this is secure against attacks that it simply isn't there to defend against.
> That doesn't mean providing the primitives to implement bad crypto is responsible for the bad crypto.
In this case, it absolutely does. Not only will people most likely put them together incorrectly (which isn't the API's fault), but it doesn't provide any defense against cases where the browser is running code not intended by the server, e.g. MITM and XSS. As soon as the browser is running bad code, this is 99.9% equivalent to existing JS crypto (the exception being the secure RNG). The trust model here just doesn't hold up.
I'd like to see a declarative way to sign or encrypt parts of a document or form submission to protect them from tampering by the origin server. But js is under the control of the origin server, so I don't see this as a security advance over TLS, just a crutch for broken apps with no non-js mode using HTTP correctly.
Minimizing the number of trusted components that are under the control of Javascript is part of the point of the interface, but as Cody and I have pointed out (and obviously you as well), there's enough left to JS that the interface doesn't really solve that problem.
One thing I would probably do as Archduke, after ordering a 70% tax on cupcakes, is have the bindings only work on HTTPS connections.
I would very much rather see higher-level crypto, especially crypto that could be used declaratively, without JavaScript. (Something similar to Enigmail, but for browsers.)
Heck, there isn't even a standard way to verify a hash on downloaded files.
For the record this is only the First Public Working Draft. A lot can and will change. We are looking for commentary to understand if we are on the right track
[+] [-] tptacek|13 years ago|reply
On the plus side: building this stuff directly into the browser image may prevent people from deploying Javascript Cryptography, which is unsafe in every environment. Systems built on the Web Cryptography bindings are at least anchored to trusted implementations of algorithms already resident in the browser.
On the minus side:
* These interfaces may have the opposite effect. Mass-market websites must support all popular browser versions. For the foreseeable future, we won't have a market in which the majority of browsers implement something like this. Unfortunately, the web crypto API is something that is very easy to duplicated "cosmetically" in Javascript. So the net effect of this in the medium term is probably negative. That said, I also understand that we've got to rip off the band-aid sometime.
* The interface is low-level. I appreciate that an API like this naturally wants to be low-level, to maximize the number of things you can build on top of it. But most of the things you could build on these particular building blocks will have subtle vulnerabilities. Not only that, but the interface doesn't appear to provide even the "envelope" abstraction that other low-level libraries present.
* So much of this design is low-level that enough of the security of the system is left to content-controlled Javascript, so many (perhaps most) of the systems that rely on this library are going to have exactly the same problem as they do now.
* The low-level building blocks they provide are incoherent. If you wanted to just expose all the little knobs and wires that it could take to implement pre-existing (and broken) crypto standards, then an interface which pretends that AES-CBC and AES-GCM are two different ways to do the same thing makes some sense; some systems need GCM, and some need CBC, and you don't have to give much thought to the difference. But this library doesn't even do that; for instance, it doesn't look like callers control the nonce in AES-CTR. A good way to sum this up: if this API succeeds in the market, there are going to be deployed, widely used systems that use RSA for bulk encryption.
If I was elected Archduke of Browser Crypto, the first standard I would propose would be a simple authenticated AES-encrypted envelope format; something like, PBKFD2-keyed HMAC-SHA256-authenticated AES-CBC messages. Something impossible to screw up, because Javascript authors aren't asked to make design decisions.
[+] [-] briansmith|13 years ago|reply
[+] [-] X-Istence|13 years ago|reply
The biggest issue I have is that unless low level primitives are available it is hard to work together with various other libraries/standards. Getting Java and OpenSSL based crypto to play nice is already harder than it should be, I can't imagine what a mess it would be to try to make it work with yet another standard. And at the same time if those low-level primitives are available people are going to use them instead of the higher-level functions because they have certain specific requirements.
---
Any specific reason as to why AES-CBC? If seeking is required wouldn't AES-CTR be a better choice? Or are you making assumptions that the payload size is small enough that decryption of the whole object is feasible?
[+] [-] daeken|13 years ago|reply
[+] [-] daeken|13 years ago|reply
I'd much rather see a simple high-level interface to crypto in the browser.
[+] [-] emily37|13 years ago|reply
http://lists.w3.org/Archives/Public/public-webcrypto/2012Aug...
[+] [-] zrail|13 years ago|reply
[+] [-] daeken|13 years ago|reply
This scares me; a lot of people are going to assume this is secure against attacks that it simply isn't there to defend against.
[+] [-] kzahel|13 years ago|reply
That doesn't mean providing the primitives to implement bad crypto is responsible for the bad crypto.
I think the main benefit of this will be improved speed over existing standard javascript crypto support libraries (sjcl, jsbn).
[+] [-] daeken|13 years ago|reply
In this case, it absolutely does. Not only will people most likely put them together incorrectly (which isn't the API's fault), but it doesn't provide any defense against cases where the browser is running code not intended by the server, e.g. MITM and XSS. As soon as the browser is running bad code, this is 99.9% equivalent to existing JS crypto (the exception being the secure RNG). The trust model here just doesn't hold up.
[+] [-] prodigal_erik|13 years ago|reply
[+] [-] tptacek|13 years ago|reply
One thing I would probably do as Archduke, after ordering a 70% tax on cupcakes, is have the bindings only work on HTTPS connections.
[+] [-] romaniv|13 years ago|reply
Heck, there isn't even a standard way to verify a hash on downloaded files.
[+] [-] darkhorn|13 years ago|reply
[+] [-] morroccomole|13 years ago|reply
[+] [-] unknown|13 years ago|reply
[deleted]
[+] [-] daeken|13 years ago|reply
[+] [-] rbellio|13 years ago|reply
[+] [-] wglb|13 years ago|reply