Is it a big deal to properly store the passwords or isn't it?
> stop working on your social shopping cart calendar application right now: I can’t trust you with my Reddit karma score, let alone my credit card number.
and that's what you said for developers using fast 1-way hashes. So it's embarrassing to use md5+salt, but not embarrassing to use plaintext?
The method we use for storing passwords is either vital or it's not-- I'm currently lost as to how you could respond like the above and have such strong feelings about the matter in other discussions.
Two thoughts I'm asking you to keep in your head simultaneously:
(1) It is very bad to store passwords in plaintext, with a naked SHA1 hash, or with a naked SHA1 hash and a salt of any kind.
(2) As bad as it is to do that, it is not a critical security vulnerability in your application to make that mistake.
The classic web pester example of a "Medium" severity vulnerability: reflected cross-site scripting ("here, follow this link --- hah, now I own your session!"). If you tell me that reflected cross-site scripting is less bad --- or even the same level of bad --- as storing passwords poorly, I'll accuse you of being disingenuous.
See downthread, upthread, and sidethread for examples of me pointing out my stance on safe password storage.
Sorry, man, I kind of can't take "disingenuous" accusations seriously as that was the word on the tip of my tongue when I read your surprising statement earlier in the thread. It doesn't sound like the same person I read before, nor from someone with your (deserved) status as a learned engineer on security matters.
The point you disagreed with was whether this was an embarrassing security flaw:
> "Embarassing security flaw"? Come on.
and that's what I'm calling you on based on our earlier discussions. I'm not making any point about how this compares to other security flaws, I'm just trying to figure out where you really stand on plaintext.
An earlier quote from you as I try to sort this out:
> People get to access password hashes as soon as you mess up a single database query. The idea behind storing safe hashes is to prevent your stupid mistakes from screwing over every one of your users. The stupidest people of all are the ones who assume they aren't going to make stupid mistakes.
So, the question at hand: Is it an embarrassing security flaw to use plaintext passwords for a modern, respected website?
It may be embarassing, and it may be a flaw, but if you sent it to Bugtraq or asked ZDI to pay you for it, you'd get laughed at. I'm not making that up, it's obviously true, so why are you arguing with me about it?
If you contract a team from Matasano to assess your website, and all we come back with is "you store passwords insecurely", we're the ones who will be embarassed. Sorry. Hate on 37s all you want, but in no parallel universe is "weak password storage" a gameover.
OK, so then to be sure I'm understanding, let me walk through how Django (in the default auth backend -- this is customizable if you want to plug in another scheme, as people often do) does it:
1. The "password" field in the DB holds a value of the form "algorithm_name$nonce$hash".
2. "algorithm_name", by default, is SHA1, but the backend lets you also use in MD5 (for backwards compatibility) or Unix crypt if you're running on a platform which has it.
3. "nonce" is the first five digits of the hex digest of a pair of floats pulled (at the time the password is set) from Python's 'random.random()' (which, of course, is a PRNG, not a truly random source of numbers).
4. "hash" is the result of applying the algorithm to the combination of the plain-text password and the nonce.
It's a bit confusingly set up internally because the code refers to the nonce as "salt" even though it's different (within the limits of Python's PRNG) for each stored password. And there's some fun legacy stuff in there that transparently switches naked MD5 hashes over to the algo/nonce/hash scheme when possible, which makes even more fun.
As best I can tell, this is the sort of scheme you're recommending, or at least that you're not outright bashing. Is that correct, or have I missed something?
We've had requests to open up the variety of hashing algorithms supported in the default backend, and AFAIK the jury's still kinda out on that one due to various compatibility issues with existing DBs and older Pythons, and the ease with which alternate authentication schemes can be plugged in.
The Django scheme is what tptacek refers to as a "naked sha1 plus salt" and recommends against, because it is computably feasible to brute force it due to sha1 being a fast algorithm. His recommendation is to use a more computationally expensive hash such as bcrypt (based on blowfish) or possibly a few thousand iterations of sha1.
I guess this is where I'm getting confused. In some places I see comments which seem to say that "naked hash plus salt" is bad when the salt is the same every time, but possibly not when the salt is different every time. And, of course, in other places I see comments saying that this isn't any good either. And then stuff which has nothing to do with salts or nonces but solely looks at the algorithm (which I don't understand, because even the most up-to-date stuff on attacking popular hashes still seems to be orders of magnitude behind the efficiency of rainbow tables, and rainbow tables don't do as well against a salt that changes with every password).
And, well, this is where I just kinda go off the rails, because it seems as if there's nothing that's ever been conceived by man that doesn't have an article by a security expert saying "what are you, some kind of idiot? Why would anybody use that?"
I don't believe that this topic is, in practice, hard to understand.
You do face the challenge of sorting through all the noise of proposals and retorts --- "what if I use a 64 bit salt?", "what if I use SHA-256 instead of MD5", "what if I use AES to encrypt the passwords", "what if I run SHA1 in Javascript and just exchange the hashes", etc, etc, etc. None of this stuff matters.
The core issue is: your password hash should be cryptographically slow. It should resist account-at-a-time brute force attacks, which are the predominant method used to crack accounts. You can safely ignore the rest of the sideshows.
And finally, I have to say that just because a topic seems annoyingly complex doesn't mean it morally has to be simpler. If security experts are telling you you're an idiot for doing X, by all means get pissed that they called you an idiot, but also stop doing X.
"And finally, I have to say that just because a topic seems annoyingly complex doesn't mean it morally has to be simpler."
I'm OK with complexity. What I'm not OK with is the impression I get that there simply is no option that won't get shouted down. "Making the right choice is complex" is fine when compared to "there is no right choice".
Nobody will shout you down for iterating SHA1 or for using one of the bcrypt/scrypt/PBKDF.
In actual fact, I won't even shout at you for using salted single-pass SHA1, as long as you don't brag about it, or talk about how your "salt" construction improves security.
Well, in an ideal world I'd be in favor of using something better than what we currently have as the default, but for now we have to strike a compromise -- SHA1 is about the "best" hash that's ubiquitously available on the platforms and Python versions we support. Down the road when we've deprecated a couple older Python releases and can rely on things like hashlib being available, it'll be time to talk about improving the default setup.
And, in the context of common use cases, I think it's probably an OK compromise -- I doubt somebody's going to devote the resources to plucking the password for a random blog, for example. Once you need tougher security, you can plug in whatever scheme you like for storing credentials and authenticating users which, anecdotally, most people seem to be doing when warranted (there are quite a few third-party auth backends floating around). And, really, if I were going to brag about anything, it'd probably be the ease with which you can do that -- one class with two methods, a settings tweak and (depending on your credential scheme) possibly a short form class that knows what the incoming data will look like, and you're done. Of course, I think we could make it even easier, so I won't be bragging about it just yet :)
SHA-512 and Whirlpool are still designed to be very fast. The point is, you want to slow down the password hashing operation. So SHA-512, SHA-256, and SHA-1 are all fine, as long as you iterate them several thousand times.
http://news.ycombinator.com/item?id=576021
Is it a big deal to properly store the passwords or isn't it?
> stop working on your social shopping cart calendar application right now: I can’t trust you with my Reddit karma score, let alone my credit card number.
and that's what you said for developers using fast 1-way hashes. So it's embarrassing to use md5+salt, but not embarrassing to use plaintext?
The method we use for storing passwords is either vital or it's not-- I'm currently lost as to how you could respond like the above and have such strong feelings about the matter in other discussions.