You’re correct. Any web app or service that uses a username/password login system should be storing their users’ passwords using a salted hash, possibly even a salted slow hash, perhaps with a pepper. If this is starting to sound more like breakfast than cryptography, don’t worry: unlike your password (hopefully), secure password storage isn’t too difficult of a topic to crack.
Plaintext and basic encryption
Storing plaintext passwords in an Internet-connected database is a pretty bad idea: if the database gets hacked, anyone who has reused one of those passwords is now at risk. And yet a disturbing number of websites still do it, probably because security upgrades are more for the customer than the company. If you want to test whether a site is doing this, try selecting the “forgot password” option. If they just send you your password instead of a reset link, it’s being stored in plaintext. Encryption may sound like a strong way to store passwords, but it’s really just a step above plaintext. An encrypted password can generally be decoded with a key, and if the hackers can find or guess it, the encryption is useless.
Hashing > encryption
A hash function is basically just one-way encryption: you convert the plaintext password to a secret code, but there’s no key to convert it back, meaning you can never derive the actual password from the hashed version. This is how most secure websites manage their passwords: With a hash, the app/site never stores your actual password anywhere, and a hacker who breaks in will only get a list of letters and numbers that can’t be decoded. Depending on how strong the algorithm is, these hashes can be pretty difficult to crack. Hashes aren’t hackproof, though. All an attacker has to do is run a dictionary of potential passwords through the hash function, then compare those hashes to the hashes in the database. When two hashes match, the hacker can just look at which password generated that hash. To save time and computing power, many attackers just use a lookup table (or a “rainbow table,” a space-saving version of lookup tables), a pre-generated table full of potential passwords and their hashes. You can actually try hashing a plaintext word and then use a lookup table on the hash yourself; it’s not too hard. Essentially, if your password is at all common, the hash of that password is probably already in a lookup table. This is a great reason not to use common passwords.
Salted hashes > hashes
Unlike slugs, salt makes hashes stronger. Since the entire hash changes even if just one letter of the plaintext word is changed, all a site needs to do to foil lookup tables is add some extra plaintext to the password before it’s hashed. The attacker will be able to read the plaintext salt since it’s stored in the database, but it forces them to recompute every possible combination of potential passwords and salts. Of course, salted hashes can still be cracked. Hackers can just add the salt to the password they’re guessing, hash the combination, and wait for matches to pop up – a standard dictionary attack. Since modern GPUs can make billions of guesses per second, this isn’t at all infeasible, but it does make the process a lot more annoying. Failing that, brute-force attacks are slow but very effective.
Making hashes even stronger: other tactics
Slow hashing algorithms, like PBKDF2 or bcrypt, use a technique known as “key stretching” to slow down dictionary and brute force attacks. This essentially involves setting the hash function to iterate a certain number of times (though it’s a bit more complex than just running the same thing over and over again), so that in order to reach the correct hash you have to use a lot of computing power. If a site is doing all this, their security is pretty good. For added security, you can also “pepper” your hashes – which hopefully are already salted. A pepper, like a salt, is a set of values attached to the password before it is hashed. Unlike a salt, however, there is only one pepper value, and it is kept secret, separate from the salts and hashes. It adds another layer of security to the salted hash, but if the attacker manages to find it, it’s no longer very useful since the attacker can just use it to compute new lookup tables.
Don’t make a hash of your hash
Password security has made some big advances – and so has the art of cracking that security. Unfortunately, humans are still bad at password management, and databases don’t upgrade security as often as they should. In general, assume that whenever you create an account, the password is being stored with relatively weak security. If your password is common or a dictionary word, then it’s at a pretty high risk of being cracked. Make your passwords long, mixing letters, numbers, and symbols, and you’ll be helping hash functions do their best work. Image credits: Hash function