“Our password database was stolen yesterday. But don’t worry — your passwords are completely safe.” We regularly see statements like this one online, but should we really take these assurances at face value?
The reality is that password database compromises are a concern. However, if you use unique passwords everywhere, you shouldn’t need to worry too much.
How Passwords Should Be Stored
Here’s how passwords should be stored in an ideal world: You create an account and provide a password. Instead of storing the password itself, the service generates a “hash” from the password. This is a unique fingerprint that can’t be reversed. For example, the password “password” may turn into something that looks more like “4jfh75to4sud7gh93247g…”. When you enter your password to log in, the service generates a hash from it and checks if the hash value matches the value stored in the database. At no point does the service ever save your password itself to disk.
To determine your actual password, an attacker with access to the database would have to pre-compute the hashes for common passwords and then check if they exist in the database. Attackers do this with lookup tables — huge lists of hashes that match passwords. The hashes can then be compared to the database. For example, an attacker would know the hash for “password” and then see if any accounts in the database are using that hash. If they are, the attacker knows their password is “password.”
To prevent this, services should “salt” their hashes. Instead of creating a hash from the password itself, they add a random string to the front or end of the password before hashing it. In other words, a user would enter the password “password” and the service would add the salt and hash a password that looks more like “password35s2dg.” Each user account should have their own unique salt, and this would ensure that each user account would have a different hash value for their password in the database. Even if multiple accounts used the password “password,” they’d have different hashes because of the different salt values. This would defeat an attacker who tried to pre-compute hashes for passwords. Instead of being able to generate hashes that applied to every user account in the entire database at once, they’d have to generate unique hashes for each user account and its unique salt. This would take much more computation time and memory.
This is why services often say not to worry. A service using proper security procedures should say they were using salted password hashes. If they’re simply saying the passwords are “hashed,” that’s more worrying. LinkedIn hashed their passwords, but they didn’t salt them — so it was a big deal when LinkedIn lost 6.5 million hashed passwords in 2012.
Bad Password Practices
This isn’t the hardest thing to implement, but many websites still manage to mess it up in a variety of ways:
- Storing Passwords in Plain Text: Rather than bother with hashing, some of the worst offenders may just dump the passwords in plaintext form into a database. If such a database is compromised, your passwords are obviously compromised. It wouldn’t matter how strong they were.
- Hashing the Passwords Without Salting Them: Some services may hash the passwords and give up there, opting not to use salts. Such password databases would be very vulnerable to lookup tables. An attacker could generate the hashes for many passwords and then check if they existed in the database — they could do this for every account at once if no salt was used.
- Reusing Salts: Some services may use a salt, but they may reuse the same salt for every user account password. This is pointless — if the same salt were used for every user, two users with the same password would have the same hash.
- Using Short Salts: If salts of just a few digits are used, it would be possible to generate lookup tables that incorporated every possible salt. For example, if a single digit were used as a salt, the attacker could easily generate lists of hashes that incorporated every possible salt.
It’s likely that the salt value is also present in the password database. This isn’t that bad — if a unique salt value were used for each user, the attackers would have to spend massive amounts of CPU power breaking all those passwords.
In practice, so many people use obvious passwords that it would likely be easy to determine many user accounts’ passwords. For example, if an attacker knows your hash and they know your salt, they can easily check to see if you’re using some of the most common passwords.
If an attacker has it out for you and wants to crack your password, they can do it with brute force as long as they know the salt value — which they probably do. With local, offline access to password databases, attackers can employ all the brute force attacks they want.
Other personal data also likely leaks when a password database is stolen: Usernames, email addresses, and more.
Help, What Should I Do?
Whatever a service says when its password database is stolen, it’s best to assume that every service is completely incompetent and act accordingly.
First, don’t reuse passwords on multiple websites. Use a password manager that generates unique passwords for each website. If an attacker manages to discover that your password for a service is “43^tSd%7uho2#3” and you only use that password on that one specific website, they’ve learned nothing useful. If you use the same password everywhere, they could access your other accounts. This is how many people’s accounts become “hacked.”
If a service does become compromised, be sure to change the password you use there. You should also change the password on other sites if you reuse it there — but you shouldn’t be doing that in the first place.
You should also consider using two-factor authentication, which will protect you even if an attacker learns your password.
The most important thing is not reusing passwords. Compromised password databases can’t hurt you if you use a unique password everywhere — unless they store something else important in the database, like your credit card number.