Hacker News new | past | comments | ask | show | jobs | submit login

The hardest part of this to read for me isn't the vulnerability, but rather:

     2011 Passwords: BPKDF2-HMAC-SHA1 with 1000 iterations
     2011 Passwords: BPKDF2-HMAC-SHA1 with 600 iterations
     2011 768 bit RSA
     2011 512 bit RSA
     2011 600 bit RSA
     2011 1280 bit RSA
     2011 1024 bit RSA
     2011 1048 bit RSA
     2011 1536/1152 bit RSA (Chrome/other)
     2011 1536/1024 bit RSA (Chrome/other)
     2011 "3072 bit" D-H	
     2011 "3072 bit" D-H	
     2011 "4096 bit" D-H	
     2012 ECC Curve25519	
(edited for clarity)

Major red flag. The difference between symmetric-keyed password-based encryption, RSA, Diffie-Hellman and ECC (presuming ECDH?) isn't minor; it isn't a feature-level distinction. These are radically different designs. I'm not sure I've ever seen a system as popular as this so quickly take a tour of so much of cryptography. How could anyone have any kind of grip on the safety of a system that fundamentally changes its crypto constructions so often?

A lesson here: if you have to implement cryptography --- and you and your users would be much better off if you didn't, and rather relied on a standard implementation like PGP --- do one thing and stick with it. Think of it like being a little kid lost in a shopping mall. Don't make it harder to get found.




What about NACL? It seems more flexible that PGP but still provides a fairly high level of abstraction. Not sure what is a good library for doing PBKDF2 or similar though.


Probably the best KDF you'll get right now is scrypt[1]. NaCl did not see common adoption because until a relatively recent distribution called Sodium[2], it was not portable. And I mean really, not portable. Like, just to give an example, suppose you want to use NaCl in Node.js, which is pretty good about accepting C/C++ modules. You have two options today: one doesn't work on a 64-bit system[3] and one isn't C, it's JS which was transpiled with Emscripten[4]. I mean, don't get me wrong: the fact that we can now do this in pure JS via Emscripten is amazing, but yeah, NaCl was not universally buildable and therefore was not reliably deployable, and nobody really wanted to fix it until Sodium came along.

[1] https://www.tarsnap.com/scrypt.html

[2] https://github.com/jedisct1/libsodium

[3] https://github.com/thejh/node-nacl

[4] https://github.com/tonyg/js-nacl


scrypt is great if you want to store passwords, but not really helpful in other contexts. Nacl is a complete cryptosystem; think of it as a stronger, more modern, library-ized version of GPG.

Don't use a JS translation of Nacl. Nacl goes to pains to ensure that it doesn't expose side channels; no Javascript implementation can make the claims Nacl makes.


scrypt is great if you want to store passwords, but not really helpful in other contexts

I'd say that scrypt is most useful when generating derived keys for file encryption. For login passwords you probably want a fairly low work factor (say, 0.1 seconds), both to make logins responsive and to make it harder for an attacker to use login attempts to DoS you; but for file encryption you can easily spend 5 seconds or more.


Using a KDF with a decent encryption algorithm (ie. AES) doesn't really help much, (it doesn't make it worse, either). Considering you'll be using something like AES-CBC, you will already have a salt/IV as part of the encryption process, and you are safe against people finding your key from multiple ciphertexts.

So there are no real problems that adding scrypt solves, besides "making it slower".


  for P in password candidates do:
    compute K = KDF(P, salt);
    M_0 = decrypt(block #0 of cyphertext, K, IV);
    if M_0 looks like plaintext:
      store P for future analysis
    fi
  od
Encryption using a passphrase needs a good KDF just as much as login password hashing does.


I may have been a bit rash to say, "there are no problems that adding scrypt solves," but whether you need a KDF for encryption is more of a practical problem. There are many circumstances where it makes sense, but I'd consider that a part of your password policy. In general, encryption is secure by itself, and I'd avoid adding unneeded steps.

As for password hashing, that is a very different application than deriving a key for encryption. You are storing the result (usually in a database), and in the case there is a leak, hoping that no one can brute-force the passwords. This is when you start the process of changing salts and work values (in the case of scrypt), and getting everyone to change their password. Using a KDF in this case makes a lot of sense.


To take a concrete example of encryption using a key derived from a passphrase: SSH keys. OpenSSH uses MD5 as a key derivation function, so if someone steals a passphrased SSH key file you'd better hope that the passphrase is very strong.


Note that it's possible to convert your keys to use PBKDF2: http://martin.kleppmann.com/2013/05/24/improving-security-of...


Using a KDF such as scrypt for that example does make a lot of sense, and after considering some others, I must admit, makes a lot of sense for most circumstances.

I also had a quick look at the tarsnap source code, and I see you do exactly that for the passphrased keyfile.


Yes -- in fact, that's why I invented scrypt, because I was adding passphrase encryption to tarsnap key files and wanted to do it as securely as possible.


Couldn't you use the output of scrypt as a key for a symmetric cipher?


You could if you were going to design your own cryptosystem, but not doing that is the point of this subthread.


Nacl still leaves you with the necessity to manage your keys, whether you're deriving them from passphrases (in which case you should use a KDF, and scrypt should work) or storing them.


Ok, that's true; if you use the secretbox APIs and aren't using randomized keys, you'd want something like scrypt. You're right.


Even if you're using the non-secretbox APIs like crypto_box.


At what point aren't you designing your own cryptosystem? Even if you use NaCl you must store your keys, determine when and when not to encrypt, decide how to generate nonces, pick between symmetric and asymmetric ciphers. I understand strongly that you should work with as large a black box as you can afford, but it becomes increasingly grey as you move toward operational stuff over "obvious" crypto stuff.


Scrypt is a Key Derivation Function, as well as a password hash, so it has a few uses. If you want to take many parameters, and make a random key, it will work well. If you want to record a secret value (ie. password database), it works incredibly well. If you want to use it on a password for something like AES-CBC, then you probably don't need it, since AES-CBC is already secure.

Most encryption algorithms are already designed to take a users key, and apply them in a secure fashion. Unless you aren't using such an algorithm, you should trust the crypto primitives that have already been built for you. Of course, many people will have special use cases, but they should already know what they are.


I really can't recommend skipping a KDF for encryption on the basis that AES-CBC is "already secure." Use of a strong KDF has a direct bearing on the compute time required for an attacker to brute force the key.


I think he means that your AES-CBC should already be doing key derivation from the user supplied password.


> Don't use a JS translation of Nacl. Nacl goes to pains to ensure that it doesn't expose side channels; no Javascript implementation can make the claims Nacl makes.

What specifically are the side channels you see that Javascript exposes?


Lack of evidence for side channels is not good enough. You deserve an encryption system that's carefully constructed to prevent all known forms of leakage.

The usual side channel is timing. Some numeric operations take longer than others depending on the key, and an adversary can measure these to narrow down possible keys: https://en.wikipedia.org/wiki/Timing_attack

Javascript engines have complicated numeric type conversion rules, together with single-entry type caches that seem very likely to leak.


> Lack of evidence for side channels is not good enough. You deserve an encryption system that's carefully constructed to prevent all known forms of leakage.

While I agree that absence of evidence is not evidence of absence I have to take you up on that second statement. I'd say you deserve an encryption that's carefully constructed to provide appropriate protection against a threat model matching the use case.

A case in point would be MD5. MD5 is vulnerable to collisions, does that mean that we should use MD5 for passwords? Of course not but because of moore's law and scrypt, not because of collisions. Should we use MD5 for hashing content? For anything forensic, no. For situations where collisions aren't important, perhaps yes.

Many software crypto systems are susceptible to direct leakage through RAM, that doesn't mean that we shouldn't use them.


Be aware that we don't know how bad browser side channels are going to be. People were surprised when Boneh and his team showed RSA key extraction over an IP network using just timing a decade or so ago; people will be surprised when someone pulls a key out of a browser by having them visit a spoofed site, too.

Why assume the risk?


As someone who's done a lot of non-crypto side channel stuff (particularly around signal modulation for exfil) I'm of the view that side channel stuff happens and it's not exclusive to crypto. State generally leaks. It's a matter of having something resilient enough for the use case not to matter.

I see where you're coming from with it but to take your point I can pull keys out of a memory dump, who cares which process it comes from? In this case does it mean we should all wait for a perfect OS that scrubs memory on everything properly and encrypts swap?

That's not to say you're wrong, I think you have some valid points but in every other domain it appears there's a good enough level and when I at least encounter UK government crypto we're told it's the same. The thing about the cryptocat thing is that there are questions about transparency that are valid (and I've seen your conversation on twitter and agree with some of your points), but I'm trying to avoid falling into that situation.


JavaScript runs inside a VM. It is impossible to avoid side-channel attacks without direct access to the CPU.


I like Nacl. I also like Keyczar. I would be very worried about a project that oscillated from PGP to Nacl to Keyczar, though.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: