Lesson 1 of 6
Lab 1 — Password Cracking Maths
Work out the keyspace of a password, estimate crack time at real GPU speeds and design a passphrase that survives.
Learn it
Attackers rarely guess your password by hand. They use software that tries billions of options a second against a stolen file of hashed passwords.
Every extra character multiplies the number of possibilities. Length beats weird symbols almost every time.
A four-word passphrase like 'copper-otter-lamp-9' is easy to remember and enormously harder to crack than 'P@ss1!'.
Key terms
- Keyspace
- The total number of possible passwords, calculated as character-set size raised to the power of the length.
- Entropy
- A measure of unpredictability in bits; each extra bit doubles the work an attacker must do.
- Hash
- A one-way function that turns a password into a fixed-length fingerprint that cannot be reversed.
- Salt
- Random data added to each password before hashing so identical passwords produce different hashes.
- Brute force
- An attack that systematically tries every possible combination until one works.
Run the numbers
Assume an attacker manages 10 billion (10^10) guesses per second against a leaked fast-hash file.
- 11. Count the alphabet: 'password' uses lowercase only: C = 26, L = 8. Keyspace = 26^8 ≈ 2.1 × 10^11.
- 22. Divide by speed: 2.1 × 10^11 ÷ 10^10 = about 21 seconds. That password is already gone.
- 33. Add complexity: 'Pa55w0rd!' uses C ≈ 95, L = 9 → 95^9 ≈ 6.3 × 10^17 ≈ 2 years. Better — but dictionary rules crack it in minutes because it is a known pattern.
- 44. Go long instead: A four-word passphrase from a 7,776-word list: 7776^4 ≈ 3.7 × 10^15 combinations... but add a fifth word and it becomes 2.8 × 10^19 ≈ 90 years at the same speed.
- 55. Slow the hash: If the site used bcrypt at 10,000 guesses per second instead of 10^10, every number above gets one million times bigger. Defence is a shared job.
Estimating crack time in Python
pythonimport math
def crack_time(charset, length, guesses_per_sec=1e10):
keyspace = charset ** length
entropy = length * math.log2(charset)
seconds = keyspace / 2 / guesses_per_sec # average = half the keyspace
return round(entropy, 1), seconds
for label, c, l in [("password", 26, 8), ("Pa55w0rd!", 95, 9), ("passphrase", 95, 20)]:
bits, secs = crack_time(c, l)
print(label, bits, "bits", round(secs / 31_557_600, 2), "years")We divide by two because on average an attacker finds the password halfway through the keyspace.
Try it
Which output line is correct for the 20-character passphrase?
textcharset = 95, length = 20
entropy = 20 * log2(95) = ?Challenge
You are the security lead for a school portal. Write a password policy for 1,200 students and staff. Justify every rule with the maths from this lab, and explain why you did NOT include a rule that forces a password change every 30 days.
Pick whichever way suits you — every mode earns the same bonus XP.
Write at least 40 more characters to submit.
Mark your own work
Guided walkthrough — 0/7 clues revealed
- Clue 1 locked — reveal it only if you get stuck.
- Clue 2 locked — reveal it only if you get stuck.
- Clue 3 locked — reveal it only if you get stuck.
- Clue 4 locked — reveal it only if you get stuck.
- Clue 5 locked — reveal it only if you get stuck.
- Clue 6 locked — reveal it only if you get stuck.
- Clue 7 locked — reveal it only if you get stuck.
Each clue costs 4 XP (never below 18 XP). You'd earn 35 XP right now.
Extension: Add a section on what the server must do: salted slow hashing, rate limiting, and breach-list checking.