scrypt all the things!

SCRYPT ALL THE THINGS

If you take away only one thing from this post let it be this:

If you have a human password, scrypt it. 1

The reason passwords suck is because humans are terrible at generating and storing entropy. (That and password reuse, but that's another story.)

And the reason that's a problem is that attackers can then bruteforce something that relies on a human password.

Scrypt and bcrypt and PBKDF2 are algorithms that will take an input (a password) and hash it really, really slowly. The point is that you can tolerate some delay when checking a password, but an attacker would have to wait that time for every try.

So, scrypt is always a (partial) solution to bruteforce. No one can bruteforce in the space of an scrypt output, so an attacker would have to run scrypt on all of its tries, making cracking 1500 times slower.2

Also, scrypt forces you to use salt.3 And this can make a system infinitely safer. There's no need to be clever with salt: if you can store it (most of the times) just generate a random one on first run and save it along with the hash/encrypted stuff. Otherwise use the user email.

Note: I'm speaking about offline/encryption scenarios here. The ones where the attacker can use GPUs. If you are worried about bruteforce on your web login panel, get your shit together, implement decent throttling, use realistic password strength estimations and drop that silly password policy.

WHAT IF I TOLD YOU

It's common knowledge that you should scrypt your password database, in case someone steals it and tries to recover the passwords. But that's not at all the use case where scrypt is the most useful! Here are a few others:

  • Disk encryption: scrypt the passphrase.
  • State file encryption: scrypt the passphrase.
  • Encrypted keyfiles (like in gpg and ssh): scrypt the passphrase.4
  • Client-side encrypted services: scrypt the passphrase.
  • Encrypted wallets: scrypt the passphrase.
  • Password storage: scrypt the (main) passphrase.
  • Brainwallets: this one. THIS. ONE. You are using a password to generate a key where to store money, and the public key will be public for anyone to bruteforce... AND YOU F*CKING USE SHA256!? Use Warp, please.
  • Anything that is encrypted with a human password: scrypt the password!

Anywhere, let's say, a diceware passphrase would make sense, the design should use scrypt. It actually, magically makes all your users' passwords better.

So... well, use scrypt. And not only in the database. And follow me on Twitter for more rants. Bye!

P.S. This is my new blog and I'm still transitioning, so most of my stuff is over at the old one. Feedback really welcome on the design readibility.

  1. This is a "piece of advice you should follow unless/until you know WHY and WHEN it's wrong"™. So there might very well be exceptions, but they're that - exceptions.

  2. Comparing performance of a R9 290X running oclHashcat (http://hashcat.net/oclhashcat/) and a R9 290X mining Litecoin (https://litecoin.info/Mininghardwarecomparison). This probably makes scrypt seem less strong than how it actually is.

  3. A salt is a unique value, not secret, but different for every user/application. This way an attacker can't just precompute the scrypt hashes of the most common passwords and then use that table every time.

  4. OpenSSH version >= 6.5 supports a keyfile format that uses bcrypt. It's used by default only if you generate a Ed25519 key. IT WAS ABOUT TIME, DAMMIT! http://www.openssh.com/txt/release-6.5