That doesn't get around the fact that the police would likely want a password in useable form, that is, something they can log in with. If you're storing something in that form, it's functionally plaintext and subject to all of the issues associated therewith. Hashing it then building in a workaround is like putting a deadbolt on your door but leaving your window open. A compromised database would have the same effect with your solution that it would with passwords stored in plaintext.
You could do this without allowing the hashes to act as passwords directly by establishing a "skeleton key" approach:
WHERE user.password = hash(input) OR hash(user.password + skeleton_key) = input
If the police want to log into a user's account without their password, they combine the hash of their password with the skeleton key, hash that, and submit it as the password.
Of course, now you have to keep skeleton_key a secret. Presumably you wouldn't store it in the same database as the password hashes, so losing the database wouldn't immediately grant access to everyone's account.
I'm not claiming this is particularly secure. In fact, it's kind of the opposite: it's intentionally adding a back door to your authentication system. But at least it's a door rather than a gaping hole :)
The problem with this approach is that now someone on the backend will mistakenly think, hey the password is already hashed by the client, let's just store that directly in the database! And now you essentially have passwords stored in plain text.
I don't understand this obsession about only storing hashes, as if that's the primary critical issue with site security. There are plenty of reasons to store the plaintext, and in a well secured database I really don't think it is much of an issue. Or as I heard someone say once, "If you can break into my database, and show me how, I will quite literally give you a million dollars".
Off the top of my head, here's a couple of very good reasons to store plaintext:
- password recoverability: if the user knows they can recover the password, they're more likely to use a more complex one
- flexibility with authentication: to use something like HTTP Digest Auth, you need the plaintext to be able to hash it with a one-time nonce
And like many will no doubt point out, hashing it isn't all THAT secure anyway. If it's not a very strong hash, or there's enough information to reset it somehow, they can get what they want anyway. Not to mention that if your database has been cracked they probably have everything they want anyway - why even bother logging in?
I just don't get it. Sure, defence in depth is the best strategy and everyone should practise it whereever possible. But whether the password is stored hashed or not is not the lynchpin security issue many make it out to be, IMO.
These are all good points and I agree with you completely.
I think I haven't explained myself well. Firstly I made the mistake of saying "plaintext" when what I really meant was "recoverable", ie encrypted but not hashed. I would never suggest that passwords be stored in plaintext, protected only by operating system and DB passwords. I didn't make that clear and I think I've deservedly gotten some heat for it.
All I am trying to say is that with enough effort, data can be secure, or secure enough. In my job I store customers' credit card information. This must be in a recoverable form. If it leaks I am dead and probably so is the company. Nothing is perfect but I have gone to a lot of trouble and I have reasonable confidence in my efforts.
Same goes for server private keys, financial records, etc. All of it is "ring 0" secure data and extraordinary efforts are made to keep it that way.
I do not actually store user passwords currently, but I know people who do. I have similar confidence in their precautions and skill. Obviously it can be done badly, just like hashed passwords can be implemented badly. But if done properly, I stand by my assertions that storing user passwords in a recoverable format can be no greater a risk than any other part of the system, and no easier or more likely an attack.
I have harped on about this enough, but I'd just like to point out two more things - one, if people enter the same login details to a honeypot then nothing can save them, and two, that crooked employees can circumvent the hashing anyway, either by sniffing inside SSL or just inserting a logging hook. Relying on hashes to thwart crooked employees is folly and could breed complacency.
Hashing passwords is a security layer, nothing less and nothing more. A site's security relies on the skill and care of its architect and staff, not on any single hot topic buzzword. Right, that's enough on this topic. Thanks for the thoughtful reply.
Yeah, I suppose I should clarify. Instead of storing the plaintext or encrypted version of the password, they should store a hash of the password. Since, if/when the database gets compromised, it's even more difficult for the attacker to retrieve the passwords.
If the passwords are just encrypted, once the attacker figures out the algorithm, then all of the passwords will be compromised. A hash, on the other hand, would require each account password to be broken individually.
Encrypting the hashes in the database would make it safer. That way the password hashes can't be attacked in this way unless they can decrypt them first.
You could encrypt it with the user’s password instead (rather than hashing it). This is also the approach taken by e.g. password managers, they use your password as a seed for encrypting all your data.
The problem is that this would make the database entirely inaccessible unless you have access to the password. That creates quite a lot of friction in the user experience, the user would have to provide his password on every interaction (ie not just when logging in).
No, you misunderstood. My example was poor, the password in the database is hashed:
... WHERE user.hashed_password = hash(input) OR user.hashed_password = input
So the user can provide their password which gets hashed and compared to the stored hash, OR the hash can be given to law enforcement if required and can be used in place of the real password.
This solves the problem of passwords being stored in plaintext (indeed a problem with frequent password reuse) while apparently getting around this silly French law.
Sure if the database is compromised anyone will be able to login to anyone's account, but the database is compromised so who cares?
Also it would defeat the purpose of having passwords hashed, because a data leak would then expose people's account just as if you were storing the plaintext password.
How does that work? Or, rather, if that can work the system has even bigger problems because you must be storing the passwords in plain text instead of salted hashes.
My reasoning was that if you can capture the hash, you could have also captured the password but that doesn't account for a situation where the database is compromised.
I think the point is that storing even encrypted passwords is not as safe as storing (salted) hashes, because if the database was compromised, the encryption key would likely be compromised as well.
It's safer if even the site themselves do not know your password.
Technically, you are right to say that there's no evidence passwords are being stored in plaintext, but encrypted stores really aren't any better.
Could that really work? Sounds like it's highly abusable if someone compromises the database and gets a list of all the hashes. Now, they don't even need to use rainbow tables or any brute force to compute the password. They just send the hash to the server and will be logged in.
Yes, exactly, so that's why I was asking, you mentioned the database was of hashed passwords. The database then contains the source passwords? And you're preventing the user from using one of those passwords?
Sorry, I still don't understand the procedure you mentioned and I'm genuinely curious.
There's a security issue with this idea obviously. If I'm not mistaken, the whole point of hashing passwords is so that a loss of the user database in some way does not compromise any accounts. You might as well store passwords in plain text if you allow hashed passwords as passwords.
It might just be acceptable though, since almost nobody would guess that a hashed password would be accepted as a password. That is, unless they have access to the controller source code too, and check it out (as you'd assume since the database itself has been compromised).
A better solution may be to create a second temporary password, hashed in another field in the database, and wipe it out when you're done.
It's fine to use an extremely long master password too, making sure it's stored as a bcrypt hash or something. Just run the calculations to make sure that it couldn't be broken in 2^999 years.
The solution is to hash the password once, salted, and store and use that as a plaintext equivalent instead of storing the real password. This way if the password is reused on other services and an attacker retrieves it from the store it isn’t as much of a disaster.
Well, it doesn't sound bad, until you rephrase it to how it will actually be implemented:
How about allowing the contents of the hash column in the database as the password?
It only takes one incompetent engineer to sometimes store the raw password in the database, and it takes two to make that work to log in somewhere (presumably an easy defense is to only allow "verbatim logins" using something the same length as a hash).
The purpose of a password hash is to protect the password authenticators in the event the database is compromised. If you define away the possibility of a database compromise, just store them in plaintext.
reply