Keeping passwords secret

4 min read Original article ↗

A couple weeks ago, it broke out that parts of Facebook’s platform stored plaintext passwords — that is, the raw password you type in the “password” field — in the database their logs (UPDATE: Thanks u/GeeWengel for the correction — this post will still use Facebook as an example, but this is not the precise problem that Facebook had). Now obviously, storing plaintext passwords is bad: anyone who has access to the database can see your password and try to use that password on different website. This could include malicious actors like people who hack into Facebook databases, in addition to actual Facebook employees — people who legitimately have access to the data. Now, Facebook did make clear that there were no signs of anyone taking advantage of the plaintext passwords, but it’s more the idea that this should never have happened in the first place. How would you feel if you found out your roommate put your TV out on the sidewalk every night for the past year? Sure, no one actually took it, but it’d probably still make you mad that they did this in the first place.

Ideally, no one (not even Facebook!) should be able to see your password, or be able to figure out your password at all. But how, exactly, would that work? Let’s first think about what logging in, as a concept, entails. First, you would type in your username and password, and click “Login”.

password-fb-1

Then, Facebook would go to the database, find some corresponding information for the username given, and somehow check that the passwords match. This is pretty straightforward if we stored the password directly in the database:

password-fb-2

But we’ve already gone through why this isn’t a good idea. What if, instead, we encrypt the password and store that into the database? Then, checking the password would simply involve decrypting the password, and then checking if they match. Encryption is a whole ‘nother topic, but right now, all you need to know is that any encryption method involves a key.

password-fb-3

This key is the main reason why this doesn’t work — where should the key be stored? If there’s one key to rule them all, Facebook employees would probably be able to get that key and decrypt everyone’s passwords. Furthermore, if that key gets leaked, everyone’s passwords are in danger. Let’s say, instead, each user had their own key; that would solve the second problem, since leaking one user’s key wouldn’t make other users’ keys decryptable, but Facebook employees would still be able to get the corresponding key to decrypt any given password. And of course you couldn’t throw away the key, since Facebook needs the key to decrypt the password to log you in.

The problem seems like quite a pickle, until, one day, you discover a magic box!

password-fb-4

Hashing: AKA One-way “encryption”

Inspecting the magic box, it seems like there’s a hole to put a password in, and a hole that gives you some response back. You discover some interesting properties about this magic box:

  1. When you put a password in, you get a seemingly random result (we’ll call this result a “hash”)password-fb-5
  2. If you put the same password in, you get the same hash (it’s deterministic)password-fb-6
  3. If you change the password even slightly, you get a completely and unpredictably different hashpassword-fb-7
  4. You can’t put the hash back into the box to get the password again; i.e. it’s impossible to go the other direction (more on this later)password-fb-8

Let’s say, now, when you sign up for Facebook, Facebook runs the password through this magic box and stores the hash in the database. Then when you return to login, if you provided the same password to log in, property #2 says that the resulting hash should be the same as before:

password-fb-9

So now we have the ability to log in. Can Facebook or anyone else who gains access to the database get your password? Aside from looking at the password you’re sending Facebook in the moment, no! Property #4 means that it’s mathematically impossible to “decrypt” the password from the hash, so the only way to figure out a password from a hash is to literally run every possible password through the magic box and see what comes out.

password-fb-10

Don’t be fooled by this; if you have a really fast computer, you might be able to try 3600 passwords per second, and if your password were 6 or fewer lowercase letters, it would be cracked in about a day. As the obligatory, oft-cited XKCD comic on password strengths explains:

Password Strength

In other words, bad passwords are still bad passwords, but the best passwords won’t help if the website saves your plaintext password directly into the database any long-term storage. So Facebook, get your act together. Sincerely, everyone.