A leak that showed no passwords
A food delivery app is broken into. The news says ten million accounts were taken. The app says passwords were not shown.
How can both be true? The app never kept the passwords at all. It kept something made from them, which cannot easily be turned back.
The one rule
Warning
Only test your own copy of a lab, and only with permission. Your lab machine is private and reaches nobody else. We look at how passwords are kept so we can keep them better. Guessing anybody else's password is a crime under the Computer Misuse Act 1990.
By the end of this lesson
Note
I can explain why a password is stored as a hash.
Key words
| Word | What it means |
|---|---|
| Hash | a fixed-length fingerprint made from some data |
| One-way | easy to work out forwards, very hard to undo |
| Salt | random text added to a password before hashing |
| Brute force | trying every possible password until one works |
| Plain text | data kept exactly as it was typed |
The cells students fill in are left blank in this preview.
A server should never keep your password
If a server keeps passwords in plain text, one break-in gives the attacker every password. People reuse passwords, so other accounts fall too.
Instead the server keeps a hash. When you sign in, it hashes what you typed and compares the two hashes. If they match, the password was right. The password itself is never stored.
Before you start
Note
Press Start the lab on the bar at the top. The lab is a whole Ubuntu machine of your own, so it takes a minute. If a Run says the machine is still starting, wait and press it again.
Hash the word cat
printf "%s" "cat" | sha256sumShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Hash Cat with a capital
printf "%s" "Cat" | sha256sumShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
One letter changes everything
Each Run prints 64 characters and a dash. The first begins 77af778b and the second begins 48735c4f. One capital letter gave a completely different hash.
The length never changes, whether you hash a word or a whole book. And nothing in the hash tells you the word.
Salt makes every hash different
Many people choose the same password, such as football1. Without help, they would all have the same hash. An attacker could hash a list of common passwords once and spot every match.
A salt stops this. The server adds random text to each password before hashing it, and keeps the salt beside the hash. Two people with the same password now get different hashes.
The same password, two salts
import hashlib
def hash_with_salt(salt, password):
return hashlib.sha256((salt + password).encode()).hexdigest()
# Two people chose the same password. Change it and press Run.
password = "football1"
print(hash_with_salt("k3Q9", password)[:16])
print(hash_with_salt("Zp2w", password)[:16])
Where Linux keeps the hashes
ls -l /etc/shadowShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Can you read the file?
cat /etc/shadowShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
The start of intern's line
sudo grep intern /etc/shadow | cut -c 1-14Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Linux hides and salts its hashes
The file is -rw-r-----, owned by root, and an ordinary user gets Permission denied. With sudo, the line starts intern:$y$j9T$.
The $y$ names the hashing method. The salt comes next, then the hash. The password StudentLab2026 is in the lab's README, but it is not in this file.
A common mistake
Warning
Many people think a hash is a kind of secret code that can be decoded. It cannot. There is no key to undo it. An attacker can only guess a password, hash the guess and compare. That is why a long password matters.
Worked example: how many guesses?
| Password | Characters to choose from | Length | Possible passwords |
|---|---|---|---|
| Only digits | 10 | 4 | 10,000 |
| Small letters | 26 | 6 | about 309 million |
| Small letters | 26 | 8 | about 209 thousand million |
| Small letters | 26 | 12 | about 95 thousand million million |
The cells students fill in are left blank in this preview.
Going further
Change the code above so it prints the full hash, then hash football1 with no salt at all.
Now explain in two sentences why a site that stores unsalted hashes is almost as bad as plain text.