What we’ll be learning
Passwords are an important part of most modern authentication systems, but they’re also a popular target for attackers. In this article, we’ll be learning about how passwords can be attacked, as well as some of the important terminology surrounding passwords and password storage.
Cybersecurity is full of terminology, and it can be hard to keep track of it all. In order to discuss how passwords can be targeted, we’ll need to review some of that terminology. Don’t worry if there are some things you aren’t already familiar with, this section will give you all the information you need for this article!
While authentication and authorization sound similar, there is an important distinction between the two. Authentication is about proving your identity, while authorization is about what privileges someone has. For instance, logging into a computer is authentication, but whether or not you’re allowed to run a certain program once you’re logged in is authorization. Passwords are commonly used for authentication.
Plaintext refers to data that has NOT been encrypted or hashed, and is stored in an insecure, easily readable format. This can mean literal text, but also applies to unencrypted data of all kinds, such as pictures, videos, etc… For example, both “password” and “qbttxpse” are different representations of the same data, but the first is in plaintext, while the other is (very insecurely) encrypted. Storing passwords in plaintext is a very bad idea.
Hashing is related to encryption, but the most important difference between the two is that encryption is reversible, while hashing is not. You can think of hashing as a sort of cryptographic blender: Data goes in, and a hash comes out based on that data, but if you’re given a hash, it’s mathematically impossible to reverse the algorithm and obtain the original data (though there are ways that don’t involve reversing the algorithm).
A password arms race
Suppose you’re a system administrator in the early days of computing, and you’ve been told to implement a password authentication system for a shared computer system. Unfortunately, there is a pesky hacker working against you. The hacker’s goal is to obtain the stored passwords in plaintext format, and your goal is to prevent them from doing so.
How do you store the passwords?
The easiest and most obvious solution is to store the passwords in a plaintext file, and make sure that only you and the authentication system have permission to read that file. In theory, this would do a fine job of protecting the passwords…
But in practice, all it takes for the hacker to complete their objective is to somehow access the file. There are many ways to go about this, from privilege escalation to just tricking the system into accessing the file for them. However they go about it, once they have the file, they have the plaintext passwords. Clearly, a better solution is needed…
Having learned from the failure of plaintext storage, you decide to encrypt the password file. That way, even if the hacker manages to get the file, they still won’t be able to read the passwords! Problem solved, right?
Well, not quite. The key used to encrypt the file needs to be stored somewhere so the authentication system can access it, and if the hacker can obtain the file containing the passwords, they can probably get the file containing the encryption key too.
Encryption didn’t work, but maybe there’s another type of cryptography that can help you in the form of hashing. Hashing the entire password file wouldn’t help you, but what you can do is hash each password within the file individually. Then, when a user enters a password, you hash the password they entered and compare it to the stored hash. If the hashes match, the password was correct. Surely there’s no way for the hacker to get the passwords now, right?
Well, sort of… Assuming you used a secure hashing algorithm, there’s only one way for the hacker to figure out what the original passwords were, and that’s to try running different strings of characters through the same hashing algorithm until they get a hash that matches the hashed password. The easiest way to do this is with a brute force attack, where the attacker tries
c, etc… when they’ve tried every single character, then they move on to
Unfortunately for the hacker, this is quite slow, especially for long passwords (where it can take thousands of years or more). Unfortunately for you though, the hacker has already stolen two lists of passwords that they now have in plaintext. Rather than just guessing randomly, they can try going through the list and hashing every unique password. This won’t crack all the hashed passwords, but there’s a good chance that it will crack some of them. This is called a dictionary attack, and is sort of like a smarter brute force attack.
What’s more, they don’t need to crack the hashed passwords one at a time: If more than one person has the same password, they’ll have the same hash associated with their account, so the attacker can make a big list of strings and associated hashes called a rainbow table. Now they can look up a hash in the rainbow table before trying to crack it, saving them time and effort.
After thinking about it for a while, you realize that there’s no way to perfectly protect the passwords: As long as the attacker is able to make guesses and check if they’re correct, they will ALWAYS be able to crack a password eventually. What you can do, however, is make it so impractical that the hacker gives up and goes somewhere else.
First, you pick a new hashing algorithm, which is much slower than the old one. This doesn’t matter too much for the user, but for anyone trying to make lots of guesses, it will make the process much slower.
Secondly, for each user, you generate a random string called a salt and store it with their username. When they set their password, you append the salt to the password before running it through the hashing algorithm, and do the same procedure to check if passwords are correct. Because each user’s salt is different, the attacker can’t use rainbow tables anymore: They have to crack each salted hash individually. Weak passwords can still be cracked by dictionary attacks, but that can be partially mitigated with training and password policies.
The hacker gets bored and decides to go do something else with their time, like some nice relaxing phishing.
Protecting passwords isn’t about making it impossible to crack them, but about making it impractical to crack them. Proper password storage is crucial for this, but so is having a good password policy: Weak passwords will always be at risk of attacks that involve trying common passwords, but this isn’t necessarily something that can be solved with a purely technical solution.