OpenCyber Academy
Bachelor's · Chapter 26 · English
Course code: OCA-094Chapter 26: OCA-094-C026

Chapter 26 — Passwords in practice

Open, free learning for anyone who wants to protect people and technology. No account is required to read this text or its worked answers.

Lesson map

Lesson 26 published. Map, example, EX076.

flowchart TD
  N0["Learning outcomes"]
  N1["26.1 Storing passwords"]
  N2["26.2 The password lab"]
  N3["Lab — Salted PBKDF2 hashing and a breached-password"]
  N4["26.3 Breached passwords"]
  N5["26.4 Practical rules"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5
  N5 --> EX["Worked example"]
  EX --> Q["Exercise EX076"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["26.1 Storing passwords"]
  N2["26.2 The password lab"]
  N3["Lab — Salted PBKDF2 hashing and a breached-password"]
  N4["26.3 Breached passwords"]
  N5["26.4 Practical rules"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> Q["EX076"]
[Learning outcomes]
    |
    v
[26.1 Storing passwords]
    |
    v
[26.2 The password lab]
    |
    v
[Lab — Salted PBKDF2 hashing and a breached-password]
    |
    v
[26.3 Breached passwords]
    |
    v
[26.4 Practical rules]
    |
    v
[Worked example] --> [Exercise EX076]

Learning outcomes

You will (1) store passwords safely with salted hashing; (2) check passwords against breached lists; (3) set practical password rules.

26.1 Storing passwords

Systems should never store passwords in readable form. Instead, they store a hash produced by a slow function with a random salt, a value unique to each password. Aisha learns that slowness makes guessing expensive for attackers who steal the hashes, and that salts stop attackers from comparing hashes across accounts. Python's hashlib module provides PBKDF2, a standard slow hashing function, which she uses in the laboratory with synthetic passwords. She confirms with the online banking supplier that member passwords are stored as salted hashes.

26.2 The password lab

The lab hashes the same password with two different salts and confirms the results differ, which is why identical passwords cannot be spotted from stored hashes. It then checks 300 synthetic member passwords against a small list of known breached passwords and finds six matches, 2.0 percent. The lab uses only a thousand hashing iterations to run quickly in class. Aisha notes that real systems use far more iterations, following current guidance. She explains the results to her seminar group with a printed example of the two hashes.

Lab — Salted PBKDF2 hashing and a breached-password check on synthetic data

"""Salted PBKDF2 password hashing and a breached-password check on synthetic data (stdlib only)."""
import hashlib, random
random.seed(9)
ITER = 1000  # kept low for a classroom run; real systems use far more iterations
breached = {"password1", "letmein", "qwerty123", "summer2024", "creditunion"}
pool = [f"word{n}-{n*7}" for n in range(1000)] + sorted(breached)
members = [random.choice(pool) if random.random() < 0.97 else random.choice(sorted(breached)) for _ in range(300)]
def h(pw, salt): return hashlib.pbkdf2_hmac("sha256", pw.encode(), salt, ITER).hex()
s1, s2 = bytes(16), bytes([1]) + bytes(15)
print("same password, different salts give different hashes:", h("letmein", s1) != h("letmein", s2))
hit = sum(pw in breached for pw in members)
print(f"members {len(members)}; passwords found in breached list {hit} ({hit/len(members):.1%})")

Run with python3 lab_passwords.py. Verified output:

same password, different salts give different hashes: True
members 300; passwords found in breached list 6 (2.0%)

26.3 Breached passwords

Passwords that appear in breach lists are the first ones attackers try. Aisha recommends that Ashfield's online banking check new passwords against a breached list and refuse matches, with a clear message explaining why. She notes that checks must happen when passwords are set, because the system cannot read stored passwords later. For the six synthetic matches, she suggests prompting members to change their password at next login. The online banking supplier confirms its system can perform such checks, and Ashfield asks for the feature to be enabled at the next update.

26.4 Practical rules

Aisha reviews Ashfield's password rules, which require frequent changes and complex characters. She learns that frequent forced changes often lead to predictable patterns, such as adding a number each time. She recommends longer passphrases, breached-password checks, multi-factor authentication and changes only when compromise is suspected. Dr. Carrow notes that good password rules consider how people actually behave, which links to the principle of psychological acceptability. The IT manager updates Ashfield's password standard accordingly, and the change is announced to staff with a short explanation of why longer passphrases are easier and safer.

Worked example

Aisha hashes passwords with salted PBKDF2, shows different salts give different hashes, finds 6 of 300 synthetic passwords in a breached list and recommends practical rules.

Synthetic case. Passwords are synthetic; outputs come from lab_passwords.py.

Errors and limits

Storing passwords without salt lets attackers spot identical passwords.

Exercises

Worked answers

EX076. It stops attackers comparing hashes across accounts.

EX077. Six of 300, 2.0 percent.

EX078. They lead to predictable patterns.