So are there situations where it is reasonable to do JavaScript cryptography?

Here's a hypothetical: you have producers and consumers of certain documents. You want a system where a producer can produce a document for a particular consumer, put it on a server, and that consumer (and only that consumer) can retrieve the document and read it. Ideally, you want to this as unobtrusively as possible from the point of view of the consumer. If the server is compromised, the intruder should not be able to read any of the documents. It's hypothetical, but something I once worked one would have benefited from such a system, so I spent some time considering how it could be designed.

One approach would be to have a public/private key pair for each consumer. When a producer prepares a document for the user, it is uploaded encrypted using that consumer's public key. The encryption would be done on the producer's client machines (producers are on a company LAN using computers administered by a competent IT department, and can be assumed free of malware).

On the consumer side, we need to solve three problems: (1) generation of the public/private key, (2) storage of the private key, (3) decrypting downloaded documents.

One approach to this would be to tell the clients to install PGP, generate keys, and send the public key to the producers. Clients could then download documents via their browser, and run PGP to decrypt them. That fails the "unobtrusive to the client" requirement.

So let's consider the JavaScript approach. The JavaScript can be delivered over SSL, with all elements of the page coming over SSL from the same server (which could be separate from the document storage server).

For generation of the public/private key, the lack of a secure random number generator in JavaScript would seem a hindrance, but is it? Couldn't a CSPRNG be used in JavaScript, seeded with something derived from the user's password? That would have entropy limited by the entropy in the user's password--but how is that different from using a secure random number generator but then storing the private key encrypted with the password? In either case the difficulty of getting the private key for an attacker is limited by the entropy of the password.

If the private key is generated as above, it can be regenerated from the password as needed so there is no need for key storage.

It seems to me that the above sidesteps most of the issues raised in the article that are specific to JavaScript. The ones that remain, where someone has compromised the client machine via another route, would also apply to a client implementation done as a stand-alone application. If the client machine is compromised, the client's documents are vulnerable.

Let me also propose one more scenario. What about JavaScript that is NOT delivered over the net on each use? For example, suppose (still using the hypothetical producer/consumer example) that when a consumer signs up for the service, the sign up server generated the public/private keys, then dynamically created a static page with embedded JavaScript that includes the private key (encrypted with the consumer's password) as data. This static page is bundled up with any other resources it needs (images, style sheets) into a zip file, and that is given to the client.

The client unzips this, and when he wants to get documents launches the static page in his browser. The static page references its resources by file:// URLs. Essentially it is an application that happens to use the browser as an execution environment. The network is only used to make an AJAX call to get encrypted documents from the server.