Live data from Hacker News

A Better Way to Store Password Hashes?

opine.me

41–50 of 59 posts

Re: A Better Way to Store Password Hashes?

#41
Seems like it'd paint you into a bit of a corner if you ever needed to change anything about your password hashing.

Say some mythical unbreakable hash algorithm comes along that's O(1) and you decide you want to move to it, you're forever going to have to drag along these terabytes of junk hashes as you're entire userbase wont log in (giving you the opertunity to change how their password is stored) and since you can't tell the noise from the signal you'll forever have that enormous table of hashes from that time you tried to be extra clever.

I'll leave crypto to the experts :)

Re: A Better Way to Store Password Hashes?

#42
post #22

Earlier quoted context omitted.

Definitely not. The back-end takes a user's password and hashes it with that user's specific salt. Then the result must be in the table. Another user's password will not work. What you are worried about is a result existing in the table, even with the wrong password. That can only happen if you have a hash collision. The article on collisions I cited ( http://preshing.com/20110504/hash-collision-probabilities ) says…

Ah OK. So effectively the salt becomes the foreign key ;-)

Actually not a bad idea. You could also hash the salt and use it everywhere instead of the user's ID - anonymize the user from their own data. (If you used the password hash, you would just have to remember to update it everywhere on password changes - and of course use a hash of the hash so you didn't give away which hash was used.)

For instance, let's say I was UserID 123 which had a FK to a table of bookmarks or history and normally it would be easy to link that user to personable data such as Cancer, Job searches, Pr0n, etc. Now instead, you have a lot of these bookmarks pointing to a hash that was used in the initial user login and not directly linked in the database.

Typically in highly sensitive databases you hash out a new "ID" entirely and reference that. Then you provide a different service and database entirely that correlates two different identities when you need identification. This is similar to how PCI requirements for credit cards store the actual numbers elsewhere and use a token against the system for consumption.

Re: A Better Way to Store Password Hashes?

#43
post #40
post #38

Earlier quoted context omitted.

Absolutely correct. A 'salt' by definition, is always random. For example, you could use a 32-byte salt with scrypt and you would get back a 32-byte hash. Both are equally unlikely to ever collide (see numbers in the article) even with trillions of entries in the table.

With this scheme random isn't quite enough though, it needs to be unique as well doesn't it?

Chances of generating two random 32-byte strings that collide are so tiny that you can as well say that they are unique.

Re: A Better Way to Store Password Hashes?

#44
Does it really matter that the hacker doesn't know which hash belongs to the user? He will still be able to do a dictionary attack using the same method you use to login.

Wouldn't this just make dictionary attacks easier? Now the hacker doesn't have to find one exact password but has the option to match any of his dictionary passwords to any of the password hashes.

I know that there are hardly any collisions and that in practise this wouldn't really change a thing. But in theory the dictionary attack would be faster this way.

Re: A Better Way to Store Password Hashes?

#45
post #43
post #40

Earlier quoted context omitted.

With this scheme random isn't quite enough though, it needs to be unique as well doesn't it?

Chances of generating two random 32-byte strings that collide are so tiny that you can as well say that they are unique.

Remember that assumption is the mother of all fuck-ups, although in this case the risk as you say is minimal.

Re: A Better Way to Store Password Hashes?

#46
post #38
post #37

I think you need to make sure that each user has a unique salt. If you happen to assign me the same salt as another user then either my or their password will unlock either account and the attacker only needs to guess the weaker of the passwords.

Absolutely correct. A 'salt' by definition, is always random. For example, you could use a 32-byte salt with scrypt and you would get back a 32-byte hash. Both are equally unlikely to ever collide (see numbers in the article) even with trillions of entries in the table.

[deleted]

Re: A Better Way to Store Password Hashes?

#47
post #44

Does it really matter that the hacker doesn't know which hash belongs to the user? He will still be able to do a dictionary attack using the same method you use to login. Wouldn't this just make dictionary attacks easier? Now the hacker doesn't have to find one exact password but has the option to match any of his dictionary passwords to any of the password hashes. I know that there are hardly any collisions and that…

1. The point of hashing passwords is to protect the password itself (the plaintext), so that users who use the same password over and over again (which is most of them) don't see all their accounts opened if one of the services they use has a security breach.

2. Collisions are not actually very likely (understatemeeeent)

3. > He will still be able to do a dictionary attack using the same method you use to login.

Sure, but that's not the point. The point is that validating a hash now requires a lookup into terabytes of data, meaning it's much harder to use ASICs or GPUs to brute-force the site, and the validation may even require hitting disk which is extremely expensive compared to even expensive hashings.

4. It also makes retrieving the data that much harder: a users table is not usually big and noticeable (especially just 3 columns thereof), a terabyte+ of data going out might show up on the network stats.

Note that I'm no cryptographer and do not recommend TFA's scheme as I can't judge one way or the other, but your objections don't hold as far as I can see.

Side-note (and weakness) for 4: on the other hand the retrieval is trivially shardable and parallelizable, so at the end of the day you probably don't gain much: the data from the GPU/ASIC hash-computer is fed into a sharded db server for matching against the hash data, it will have a cost impact but depending on the cost of the hashing function itself it may not even increase the overall operation time.

Re: A Better Way to Store Password Hashes?

#48
post #43

Earlier quoted context omitted.

Chances of generating two random 32-byte strings that collide are so tiny that you can as well say that they are unique.

Remember that assumption is the mother of all fuck-ups, although in this case the risk as you say is minimal.

It's not an assumption, it's a fact.

Re: A Better Way to Store Password Hashes?

#49
NO! This is a bad idea:

"When a user logs in, you retrieve the salt for the given user, re-compute the hash as you normally would, and simply check if the resulting value EXISTS in the Hashes table. If it does, you consider the login as successful."

This will cause false positives. Let's say that of the trillions of hashes, one is the one we want... But what if one brute forces the system? What if one of the brute attempts matches ANY of those trillions? Bam. Access.

This is a very very bad idea.

Do not roll your own security unless you know what the F&#@ you're doing. You are trading a compromised security issue (your attacker already has access enough to get the hashes/users) for a uncompromised security issue (your attacker does not have access to the hashes/users, and is just trying to get in via brute force).

You are making it easier for the non-secure access attacker by making it harder on the secure access hacker. You are making the most common threat bigger to make the least common threat smaller.

Let me explain it using the pigeonhole principle.

Say you have 2 pigeons (passwords) and 1 million pigeon-holes (hashes aka possible passwords). Assuming all the pigeons are in a hole, and you reach into a random hole, what is the chances of pulling out a pigeon (password/hash collision)?

Now, let's say you have one hundred thousand pigeons (What OP is suggesting) and the same million holes... What are your chances of pulling a pigeon out of a random hole this time?

I wish I could use font-size 1000px right now.

Do not do this. Do not do this. This is a compromised system, right off the bat. If you are securing people's private data or possessions in this manner, you are doing them harm.

As more users sign up, the chances of brute forcing actually increases (more hashes to possibly match!). Let me repeat that in a different way: EACH USER MAKES THE SYSTEM LESS SECURE.

Besides all that, let's say you have to do an EXISTS check on a million records. That means you will check each one until you find a match. That is a linear complexity, that is O(n), unless you index the column, which is expensive. Could take a while, depending, but most certainly will take longer than searching for something with a known key that is indexed efficiently (being an index on a primary key), which should give you something like O(log n) which is much faster.

I don't mean to be an ass, but please downvote this so that there is less chance of people implementing this.

OP; you are suggesting a very harmful idea. Remove it if you have any amount of goodwill towards the community.

I work in web security, and used to work for a credit card merchant processor. At one point, I had access to and had to secure millions of accounts with authorization information for their credit cards; this being information one could use to empty a bank, no questions asked.

I Really Know what I'm talking about. THIS IS A BAD IDEA.

Re: A Better Way to Store Password Hashes?

#50
post #36
post #34

This would increase the complexity of the hash verification by log2(N) times, where N is the number of user records. So even if you do have a billion hashes, you only slowed the attackers 30 times. You might as well increase the BCRYPT complexity and skip this scheme.

This should be used with scrypt or bcrypt set to the highest difficulty your application can support. The point is to increase difficulty of targeting an individual user, and increase difficulty of stealing the data in the first place. This is separate and distinct protection from what scrypt/bcrypt gives you. [Edit] In a typical GPU accelerated brute force attack, the target hash and salt are both known as fixed 20…

Actually, I was wrong about O(log(N)), the lookup time is O(1), you just have to put all known hashes in a map structure, or even better, a rainbow hash.

So your technique only adds some constant lookup time.

Instead of

    if (hash == target_hash) ...
you will do

    if (map[hash]) ....
Sorry, I think you are wrong.
Post reply on HN