Hacker News new | ask | show | jobs
by samd 4678 days ago
In case anyone hasn't already seen it: http://codahale.com/how-to-safely-store-a-password/

tl;dr

Use bcrypt.

3 comments

In case anyone hasn't already seen it: http://www.tarsnap.com/scrypt/scrypt.pdf

tl;dr

Use scrypt.

Use scrypt if you can. But don't get too hung up on this. All the modern KDFs are fine; use PBKDF2, bcrypt, scrypt, whatever you have available. Just stop "salting hashes". Attackers laugh at salted hashes.
I'm sorry if I'm misunderstanding, but are you saying that application developers should not use salts at all?
I'd interpret the GP as "Application developers should not create Key Derivation Functions (KDFs)." They should choose an existing, well reviewed KDF and read up to understand its relevant best practices.

For example, PBKDF2 does require a salt (as does scrypt, which relies on PBKDF2 for its implementation). It also comes with specific recommendations on the salt's minimum length. Salting an MD5 hash is pointless in the face of modern attack methods -- rice paper against a tiger.

Wouldn't individually salting MD5 still help with large databases? With a database of 1,000 users the individual salt should slow down attackers by a factor of around 1,000.

If they are targeting a single user it doesn't help though.

It falls in line with running you ssh on an obscure port or putting your password database in .hidden/. Most likely it is just a false sense of security and security though obscurity. You are doing X,Y,Z and W and in the end you could have just used a KDF.

If anything the false sense of security plays tricks on you psychologically "oh look we have put our database in a .hidden directory. Nobody we'll find it here" and that makes you not pay attention at the weakest vulnerability -- a weak algorithm or parameters of the encryption.

Yes, salting has a role to play. That is not the point. The point is that use of a weak underlying Key Derivation Function makes the benefits of salting nearly moot.

To fully spell it out: MD5 is a very weak KDF.

I would recommend looking into the KDFs mentioned in the comments here as alternatives: PBKDF2, bcrypt, scrypt.

Not enough to matter. Attackers haven't been dependent on rainbow tables for a while now. As discussed in the article, they're using GPUs to hash guesses individually for each account.

More to the point, using MD5 for password hashes isn't acceptable, at all. Not even with any extra layers of security. Not with salts, not with extra rounds of MD5, not when combined with SHA1, etc.. With reasonable options (like bcrypt) available in every major programming language, there's no reason to use something provably ineffective like MD5.

Sure, salting definitely helps. A little.

It's like telling someone being shot at to stand sideways, because their profile is smaller that way. The right thing to tell them is to get the hell off the firing range.

The problem with salting is that people feel they're safe, and stop thinking about security there.

This table of hash functions should show you why MD5 is never to be used when privacy/security is a concern...

http://valerieaurora.org/hash.html

MD5 first started coming under pressure in 1994 and was cracked in 2004.

He's saying that rolling your own with functions designed to run as fast as possible, with or without salt, is not going to give you much security.

What you want is functions that run slowly, thus increasing attack cost.

Moreover, unless you are Schneier or tptacek don't create your own obscure slow function, use a well known one like scrypt.
unless you are Schneier or tptacek

ahem...

He's saying that if you can't use bcrypt or something like it, you should store passwords in plain text.

Like a broken record people like him/her chant "no security at all is better than security by obscurity".

I do not believe that this is what he is trying to say. He does not mean "use plaintext" when he says "don't salt hashes." He means "use a key derivation function."
> if you can't use bcrypt or something like it, you should store passwords in plain text

No, he's saying that if you can't use an acceptable hashing function, you shouldn't store passwords at all.

But, why would you be unable to use at least one of the suggested hashing functions, anyway? It's hard for me to imagine a language or platform where none of those functions is available, excluding very simple, special-purpose systems like PLCs.

Have you heard of Google App Engine?

You can't use any python module that runs C, which rules out bcrypt and its ilk.

Or even better dont't even store them at all.

If its an internal app use LDAP, Active Directory, or whatever other centralized ID system your company has. If it's a public app then consider using a federated approach like OpenID. It doesn't make sense for everything but if you can avoid storing passwords entirely then it's one less thing that can go wrong[1].

Course if you do store them then yes:

scrypt > bcrypt > PBKDF2 > ... If you get to here then you've got a problem!

Just make sure you choose a same number of rounds. PBDKF2 is fine for most folks if you have a large enough number of rounds. The old recommended default of 1K is not large enough. Ditto for bcrypt with a work factor less than 10 (or better yet 12). Your bet bet is to either use scrypt (who's defaults are paranoid enough) or choose a work factor for bcrypt/PBKDF2 that's has a decent CPU time (say .5 to 1s).

[1]: Though you do have to worry about the risk of compromise of the party your delegating too. For apps where this makes sense (say Google+ login to a Grouppn knockoff) that's a fair enough trade off for you an your users.

Not sure why you're downvoted, but the idea of actually not storing passwords seemed intriguing to me, if it was actually possible.

I did a little bit of research and I found the Secure Remote Password protocol [1]. Interestingly, this protocol does appear to protect against the case of a stolen password database. If true, that would mean that when site X loses control of the password database, that would be OK as this is designed to be secure against that attack.

I wonder why it's not been implemented anywhere widely. Anyone more knowledgeable about the security field care to comment.

[1] - http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol

Yeah I'm not sure either about the down vote. By not storing passwords I meant delegating to an external authority for authentication services. Whether that's OpenID, Persona, Facebook login, direct OAuth integration with a limited number of parties (ex: GitHub and Google Plus) can be decided on a per app basis. The important thing is the if your app use case allows you to delegate out authentication to an external party (again it's a non-trivial "if" to decide this) then you don't have to store or deal with passwords at all (and by extension don't need to worry about handling password DB leaks or hashing algos).
OpenID is a horrible idea. I have like a bunch of them, and I never remember if I signed up with Yahoo for this site or Google or whatever.

With Persona at least I know which email I use to sign up for random websites. I hope it succeeds.

Is there any reason why you wouldn't use bcrypt + random, individual salt? Am I right in assuming that bcrypt would protect against brute-force attacks and salt protects against pre-computed bcrypt rainbow tables? Or is the salt basically useless?
bcrypt is already randomized, as is every other modern KDF. There is no such thing as a bcrypt rainbow table. Rainbow tables have never really mattered. Stop thinking about rainbow tables.

You need to be using real KDFs to store passwords. Salted hashes are not real KDFs.

Thanks very much for that explanation. I'm not a computer expert, but I'm endlessly fascinated by passwords and cracking.

When it comes to picking passwords that humans can remember, what's your opinion on Diceware? Do five or six word passwords still stand up with the increases in computational power? http://world.std.com/~reinhold/diceware.html

I think it's important to pick a password that isn't in a list, or likely to be 1-2 transformations away from being in a list, and it's important to use a longer password, but apart from that it shouldn't matter as long as you use a different password for each service, and as long as the apps you use use bcrypt or some other real KDF.
Would it be useful to check password hashes against well-known lists of passwords? If so, it sounds like a service would be doing pretty good if they:

1. Required >7 character passwords

2. That don't appear on (constantly updating) lists

3. Using a reasonable KDF (b/scrypt)

Sound right?

That sounds fine to me.
$300/hr also buys a lot of $5 wrenches.
60 $5 wrenches doesn't help the attacker if I'm not physically on the same continent. Attacker needs to know where you are and have physical access... and as we all know, once you have physical access, it's game over :)
Remember: you'll be hard pressed to buy a quality wrench for 5 dollars, and - perhaps more importantly - why are you breaking them in the process?!

I suspect your process should use the wrench on lower wear items than computers, for example the desk (if plastic or wood) and things sitting around it.