Leaving aside the “Crypto in JS delivered over the web: Don’t do it”, I will offer a couple of suggestions.
> at GlobaLeaks we're undergoing implementation of client-side encryption > with server-side storage of PGP Private keys. I understand why you are looking for ways to make this less scary. As you probably know, this makes your servers a very juicy target. > Obviously the hashing to be used for storing such PGP private keys has > to be strong enough, with valuable key-stretching approach. Yes. Though I’m not sure that hashing will be enough. > We're now considering using Scrypt with some finely tuned parameters, > but we've concern regarding it's performance in the browser as a JS > implementation. Yes. That is going to be a problem (I will offer an alternative approach below) > PBKDF2 is available from WebCrypto API I don’t know that your time-line is, but it I believe that only Chrome Canary actually implements this at the moment. > and, as far as i read and > understand but i'm not that low-level-crypto expert, is used internally > to scrypt. Although scrypt makes some use of PBKDF2, you won’t be able to simply build scrypt out of PBKDF, nor will you be able to build > Does anyone know of any scrypt implementation that try to leverage the > WebCrypto API? Even if you need the whole client-side crypto delivered in the browser, I don’t think that you will find scrypt in JS useful, as the performance means that you will not be able to put set parameters in a way that will thwart the kinds of attackers that you can expect. So I’m going to make multiple proposals that can be adopted independently of each other. 1. Split password hashing between server and client. Have the client do as many PBKDF2 rounds as you can get away with, and then use the result of that as a input to your use of scrypt server side. 2. Use SHA-512 in PBKDF2 This will make PBKDF2 resistant to GPU based cracking efforts. Note that this is resistance to attacks using current, off-the-shelf, hardware. It is only a short term solution. 3. Use a second factor. Client side, you can combine the processing of the user’s password with some data from some second factor (stored in a file on a USB device or the like). Of course if they lose that data, they will be locked out forever. This is really the thing that will make it impossible for attackers who get copies of your stored data to be able to decrypt what you have stored. A couple of notes: Things like PBKDF2 and scrypt will never protect you from well-resourced attackers. This is because the cost to both the defender and the attacker are of the same order. And so, that gives the advantage to those who can through more resources at the task. As computing gets cheaper, the advantage shits towards the attacker. This is unlike what we have with security factors of other sorts of things, where the work needed by the attacker rises exponentially compared to the polynomial cost to the defender. You are correct to want client-side crypto, but because you are delivering the crypto from the web, you are not providing the benefits of client side crypto. Someone who gains control of the server you deliver the JS from or gains control in transmission can deliver a malicious client to the user and capture everything they need. This isn’t about JavaScript, but it is about how easy it is for an attacker (or you) to provide a malicious client to your users. Cheers, -j _______________________________________________ cryptography mailing list cryptography@randombit.net http://lists.randombit.net/mailman/listinfo/cryptography