3 ms·
So do multiple things to make it harder for the naughty people, i.e. hash and then encrypt the result. Hashing or Encrypting? 1) If you have to choose one or
by alexkus 13y ago
So do multiple things to make it harder for the naughty people, i.e. hash and then encrypt the result.
Hashing or Encrypting?
1) If you have to choose one or the other then obviously hashing (with a random salt and a relatively expensive algorithm, e.g. bcrypt et al with suitable work factor) is generally the way to go.
But it is still possible to brute force many of the easy passwords from a DB leak of bcrypt() hashes, it just takes a bit of time. From there you get to know that email address X uses password Y, which may open the door for hacking into other accounts where they've used the same passwords.
The people that get fucked over first from a DB leak of hashed passwords are those with weak passwords. A poor hashing algorithm (unsalted MD5, etc) may even expose seemingly "unguessable/random" passwords thanks to rainbow tables.
Even with bcrypt() hashed passwords you should be able to work through a huge portion of the top 100 passwords for all 130M accounts and come out with a huge number of email/password pairs.
Increasing the work factor of the hashing algorithm is a trade off, too high and you'll soon need extra servers just to cope with the extra CPU load of people logging in and having to check their passwords, too low and the hashes are easier to crack.
2) But, why not use bcrypt() to hash the passwords, and then some encryption algorithm to encrypt the resulting hashes?
Before anyone jumps in with it, doing this is not "security by obscurity" because you're not relying on the encryption key remaining secret alone to protect the password.
What it does protect you from is a basic leak/dump of the DB being open access for those who want to try cracking the bcrypt() hashes.
They're left with an initial problem of finding the encryption key before they can even start on the bcrypt() dictionary attack.
Sure it just takes someone to grab a copy of the login code (or wherever the encryption key is being stored) but you've protected yourself from a basic SQL injection attack that could be used to just dump the DB without access to the server to compromise the login code.
Also, hints:-
Why weren't the hints encrypted? (Including having a random n character 'salt' that is prefixed to them before encryption to prevent the same hints encrypting to the same string).
If the hints were encrypted you couldn't use them to help guess passwords.
Even if the passwords were hashed rather than encrypted, the unencrypted treasure trove of password hints would make the job of cracking the passwords much much easier.
Why were the hints even stored in the same table (or even on the same server) as the passwords? (Maybe they weren't and the hackers got both and combined the two datastores.)
Again, if the server was compromised enough that the source for the login code was obtained then the hints would effectively be in plaintext, but you've still protected the hint data from a simple DB dump hack.
- StavrosK 13y agoI'm sorry, how can you check easy passwords with bcrypt? Hell, checking just one password per account, assuming bcrypt takes around half a second (what most reasonable implementations take) would take two years. If you want to check the 100 most common passwords for everyone, that's 200 years right there.
- alexkus 13y agoSure, someone on a single machine isn't going to get far, but that's not a great defence to rely upon. The answer is one of two things:- Botnets, which most hacking groups will have some access to. Being in control of a modest 10,000 machine botnet reduces that 200 years to about a week, call it 5 weeks if you limit utilisation to 20% of a single core. Expect more of this when bitcoin mining on botnets becomes less profitable. Also, despite bcrypt() being designed not to be easy/fast to implement on GPUs because of the memory footprint required, GPUs are growing in size and reasonable implementations exist for FPGAs. ASICs would be even faster. Upping the work factor to compensate for this makes more work for the CPUs at the site that is using bcrypt(). I know of one company that has more cores utilised in performing bcrypt() checks than they do running the HTTP and DB portions of the site.
- Dylan16807 13y agoHalf a second sounds pretty slow for authentication servers handling over 100 million accounts. Here's how I figure it: Assume about 10ms per attempt, since this is a high-throughput login system. Use a whopping 10 computers to do the cracking, and you're already under a month to try most of 100 passwords on every single account. When using an awful password, bcrypt can only do so much. It can protect you from the ideal case of a single person with a single core that doesn't filter accounts in any way. Now consider how many people have access to this database...