Ask HN: How should I store passwords?

10 points by PLejeck ↗ HN
I've been told to "use bcrypt", but is bcrypt really all that stronger?

All the arguments I have seen in favor of it simply argued that it is good because it's slower than crippled molasses going uphill in January, but with a well-secured NoSQL and a properly rate-limited login system, is that really necessary?

I've been looking at SHA-512 with multiple salts, but what do you use or suggest I do?

EDIT: Just an FYI, we're a startup that will be dealing mostly in accounts of the social network variety. We will deal a bit in financial info, but mostly just user data.

15 comments

[ 4.1 ms ] story [ 70.7 ms ] thread
No matter you smart you think you are a bad guy might end up with your user table one day, and on that day you'll hope he can't crack your passwords easily.

You can control how slow bcrypt is by specifying the wok factor variable. In this context "slow" is maybe 100ms to check a password. This shouldn't be a problem on almost any web site.

Use bcrypt.

But I'm wondering, does increasing the work factor actually make the algorithm stronger?

Am I still risking bcrypt being cryptographically broken?

Increasing the work factor makes it slower to check a password, that's all. Your home grown SHA-512 algorithm is more likely to be broken than bcrypt.
This is generally considered the best summary of the topic and bcrypt is strongly encouraged, to say the least: http://codahale.com/how-to-safely-store-a-password/

I don't think the concern is so much hacking your login than it is what happens if someone grabs your user table.

That said, I suspect what you are proposing is stronger than average even among the HN crowd.

If you think it is unlikely that you will leak your NoSQL database, a quick mental comparison for you: how many man-years have gone to hardening the protocols for access to your NoSQL database? How many have gone into hardening the protocols for, e.g., MySQL? How many MySQL dumps made it to the Internet last year?

Use bcrypt. It upper bounds the loss of your database at somewhere below "Most of my users get their email accounts and bank accounts compromised."

SQL is text-based, and therefore injections are far easier. NoSQL (specifically Mongo) does not generally just plug user-provided info into a string, and is therefore secure against injections.

Age does not matter. In many cases, youth can even be beneficial, since it can include more modern techniques.

You're being overly restrictive in thinking of the attack space. For example, do you think keys in your NoSQL engine of choice necessarily always work out well if they include malformed Unicode characters? Do you think all buffers are safe? etc, etc

Talk to tptacek about this if you think NoSQL means No SQL Injections So I'm OK.

bcrypt vs SHA-something is a cryptographic decision. You've already decided to store hashed & salted passwords, great! However now you have a decision to make about which is the better cryptographic system. Listen to what the cryptographic expects say about that. They don't say use SHA.

You site might be just a simple "social network site, nothing serious like banks", but loads of people use the same password for their email. Once you have someone's email password, you have the keys to the kingdom.

The problem is, I've actually not seen anything arguing that bcrypt was cryptographically stronger, only thing arguing it was exponentially slower.
Isn't that enough of a reason to use it?

It (currently) doesn't seem likely that either bcrypt or SHA-something are going to be busted open by a flaw in the algorithm.

On the other hand, the fact that bcrypt has a large work-load makes it significantly less likely to be broken by someone running a cluster of GPU-equipped EC2 instances.

Let me ask it this way: What reason do you have for not using bcrypt considering everyone seems to suggest it? Do you worry that it's too slow? Or that the implementation is weak? Or something else?

I'm worried that the system is too slow for too little benefit. I'm also worried the CPU usage might also be higher than a simple SHA-2 hash.

I also worry that it's not really as "future-proof" as people seem to think. Every algorithm gets busted open eventually, given Moore's Law, they can try more ways faster. Plus, once we have quantum computing, all the cryptographic algorithms we know and love are busted wide open. Hell, AES has been busted already in quantum computing!

Although I gave out about arm chair cryptography, here's some arm chair cryptanalysis:

The NSA created SHA-512. They are in the middle of choosing a successor, implying that SHA-512 isn't good enough any more and it's time to have a backup.

The Wikipedia page ( http://en.wikipedia.org/wiki/SHA-512 ) lists some cryptographic flaws, which implies it's time to start retiring it.

The mathematical strengths of bcrypt vs SHA-2 are totally irrelevant.

SHA-512 is plenty big enough to require age-of-the-universe-scale CPU-effort to crack. For what it was designed for. But it simply wasn't designed for storing short bits of text like passwords. Anyone using it for that is using it wrongly, and has built a system that is far, far more prone to cracking than the theoretical strength of SHA-512 suggests.

Once you go beyond even basically competent crypto, the only thing that matters is how fast you can try likely passwords.

For passwords, SHA-512 is no better than MD5, because though MD5 has theoretical issues, no sane person will ever do a math attack on MD5 to crack your password, when they can just try all combinations of likely passwords in a few seconds or minutes.

And SHA-512 is no better than MD5 if I can try passwords at the same rate. Because I'm going to guess your password in the same amount of time. Even if you had a SHA-65536. The only practical reason SHA-512 is better for passwords than MD5 is that it takes a good chunk longer to calculate (but not long enough!).

So it is the rate of hashing, not the 'power' of the algorithm you need to worry about. And that is why bcrypt is what you should use. It isn't that it is stronger crypto, strength is irrelevant: it is slower crypto. And that's what you need when you're handling passwords.

As for 'we have a secure db and rate limited login' - why not use plaintext passwords then? SHA based hashing is only a few days CPU more secure than plaintext for short passwords. In both cases you're banking on nobody having access to the database. If you can guarantee nobody has access to the database, and you're rate limiting your logins, then why not use plaintext? No. You use password hashing explicitly because you can't guarantee db security. So use the right tool for the job.

tl;dr - Use bcrypt, it is many orders of magnitude more secure than SHA-2-based approaches.

May i suggest my own secure system: It is well known that the weakest part in any security system is the password, not many remember them and most of the people (especially the average ones) just hand write them and stick on the monitor. Solution- create a system of your own inside your brain to remember a password, do not use a software, application, stick note or else. use your own brain.
Don't store passwords. Use OpenID/OAuth/XAuth, etc.