Hacker News new | ask | show | jobs
by tptacek 3184 days ago
The most popular post that ever ran on Matasano's security blog was the one where I encouraged people to migrate to bcrypt. In 2007. Bcrypt, of course, is much older; Niels and David invented it as the standard password format for OpenBSD back in 1999 --- and bcrypt was a response to FreeBSD's iterated salted hash format, which also had a work factor, and is years older still.

Today, in 2017, bcrypt remains a sound recommendation. You can do better, but for password databases on websites, not materially better.

Salted SHA-1 hashes (salted SHA-anything hashes) were malpractice in 2012.

3 comments

> You can do better, but for password databases on websites, not materially better.

Do you mean using scrypt? What do you mean by materially better?

No, I mean bcrypt.

Scrypt is better than bcrypt, but mostly not in ways that make much of a difference in 2017.

PBKDF2 comes close to being materially worse than bcrypt and scrypt, because it's especially straightforward on modern hardware, but even PBKDF2 is fine.

For the most part, as long as you're using anything with a KDF-like design for your password hash, a compromise of your password database is going to reveal the very terrible passwords and only those passwords; the rest will be too costly to crack.

Right now given the choice I'd use scrypt and go slightly out of my way to get it (if there was a good 3rd party library for it and bcrypt was in the standard library and I was like a "yarn add" away from having it, I'd take that step), but I would not convert a bcrypt site to scrypt.

Considering that PBKDF2 has adjustable difficulty parameters would you still say it's worse if very high difficulty parameters are chosen?
It has to do with defender's vs attacker's costs. PBKDF2, which is usually instantiated with SHA-2, even with huge amount of rounds is still a lot cheaper for the attacker than for the defender, since the attacker can use GPU/ASIC, requiring fewer transistors, running many calculations in parallel, while defenders usually use CPU. On the other hand, bcrypt, scrypt, Argon2 don't provide a lot of advantage to the attacker compared to CPU, since GPU and ASIC implementations are expensive and memory-bound.

PS My measurements show that pure JavaScript implementation of scrypt is better than fast native PBKDF2 provided by WebCrypto API or Node.js at the same running time.

PPS But yeah, if you can't use bcrypt/scrypt/Argon2, but can use PBKDF2 with high number of rounds, sure, do it.

Thanks for the reply. I appreciate the added explanation.
Yes to scrypt, but these days, Argon2[1] is the best.

"better" means "cannot be calculated much faster on GPU or even FPGA because it requires a lot of RAM".

"materially better" probably means "less than a million of hashes per second on eight Nvidia GTX 1080 running hashcat"[2], so Django and scrypt are both good (adjust work factor as needed, of course).

1 - https://en.wikipedia.org/wiki/Argon2

2 - https://gist.github.com/epixoip/a83d38f412b4737e99bbef804a27...

Thanks for the reply, and added info on being materially better.
> Salted SHA-1 hashes (salted SHA-anything hashes) were malpractice in 2012.

I'm pretty sure this is still the only option on Google App Engine. You can't upload C code, so bcrypt isn't an option.

You can't store passwords as salted SHA-x hashes. It's not OK to do that. If you have SHA-anything, you have PBKDF2; use that.
It has never been the only option on Google App Engine (GAE). Bcrypt is exactly what I used in my GAE app back in 2009, though I have since moved on to scrypt. Bcrypt can be implemented in non-C languages, and there are libraries available for all the languages that are supported on GAE. If you're worried about Python performance, then you can have the bcrypt function in a separate module written in Java/Go.
Malpractice? Someone using SHA-1 for password storage wouldn't even be a medium severity issue on a modern pentest.

I agree with you, but it was very strange to discover that password storage is basically ignored in pentests. Especially after years of you drumming it up as a big deal.

Using SHA-1 for password storage would be sev:low in a pentest. There are a lot of other sev:low things that you would certainly agree are signs of incompetence. Unsoundness of engineering and vulnerability impact are almost orthogonal.
The issue is that companies can basically ignore sev:low findings. "Malpractice" implies that they need to care; they do not.

I wish they did. It would be nice if they were forced to care. But it wouldn't block them from being declared secure by a pentest. Low-severity findings are findings, yes, but they don't have the same pull as medium or high severity vulns.

All of this is true for storing passwords in plaintext, too. If some company leaked plaintext passwords, people would be outraged. Yet pentests would still give that company a pass, because plaintext password storage is sev:low.

I understand what you're saying, but second-order findings on pentests don't get high severity, no matter how important a sign of unsoundness they are. Severity and importance are also somewhat orthogonal.