◇ OpenCyber Academy
Technical · Chapter 17 · English

Chapter 17 — Contained laboratory II

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

Chapter 17 — Contained laboratory II

Lesson map

Lesson 17 published. Map, example, EX065.

flowchart TD
  N0["Learning outcomes"]
  N1["17.1 Why password hashing differs"]
  N2["17.2 Lab with scrypt"]
  N3["Lab — scrypt vector and salted storage"]
  N4["17.3 Detect, fix, verify"]
  N5["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5
  N5 --> EX["Worked example"]
  EX --> Q["Exercise EX065"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["17.1 Why password hashing differs"]
  N2["17.2 Lab with scrypt"]
  N3["Lab — scrypt vector and salted storage"]
  N4["17.3 Detect, fix, verify"]
  N5["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> Q["EX065"]
[Learning outcomes]
    |
    v
[17.1 Why password hashing differs]
    |
    v
[17.2 Lab with scrypt]
    |
    v
[Lab — scrypt vector and salted storage]
    |
    v
[17.3 Detect, fix, verify]
    |
    v
[Synthesis]
    |
    v
[Worked example] --> [Exercise EX065]

Learning outcomes

You will (1) store passwords correctly with a memory-hard function in a lab; (2) contrast fast hashes with password hashing; (3) run a full detect-fix-verify cycle on a lab service.

17.1 Why password hashing differs

Lumen's customer portal stores passwords, and Priya asks Tomás to check how. Storing them in clear or encrypting them reversibly lets anyone with database access recover them. A plain SHA-256 is better but still weak, because attackers can test billions of guesses per second on graphics cards. Password storage needs a deliberately slow, salted function such as scrypt, defined in RFC 7914, or Argon2id, defined in RFC 9106. A unique random salt per user stops precomputed tables and makes identical passwords produce different stored values. Tomás will configure such functions through libraries, never invent his own scheme.

17.2 Lab with scrypt

In the isolated lab, Tomás uses hashlib.scrypt from the Python standard library. He first checks it against the RFC 7914 test vector with password and salt NaCl, so he knows the call is correct. He then stores two synthetic users with the same password and different salts, and shows that the stored values differ while verification succeeds for the right password and fails for a wrong one. The lab output below records these results. Parameters such as cost factor and memory are chosen by policy; the small values in the vector exist only to make the test fast.

Lab — scrypt vector and salted storage

# hashlib.scrypt: RFC 7914 test vector, then salted storage for synthetic users. Teaching only.
import hashlib, hmac, secrets
v = hashlib.scrypt(b"password", salt=b"NaCl", n=1024, r=8, p=16, dklen=64).hex()
print("RFC 7914 vector match:", v.startswith("fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b373162"))
P = dict(n=2**14, r=8, p=1, dklen=32)   # lab parameters; production values come from policy
def store(pw):
    salt = secrets.token_bytes(16); return salt, hashlib.scrypt(pw, salt=salt, **P)
def check(pw, rec): return hmac.compare_digest(hashlib.scrypt(pw, salt=rec[0], **P), rec[1])
ana, ben = store(b"Depot-Spring-26"), store(b"Depot-Spring-26")
print("same password, stored values differ:", ana[1] != ben[1])
print("ana correct password:", check(b"Depot-Spring-26", ana))
print("ana wrong password:", check(b"Depot-Spring-27", ana))

Run with python3 lab_scrypt.py. Verified output:

RFC 7914 vector match: True
same password, stored values differ: True
ana correct password: True
ana wrong password: False

17.3 Detect, fix, verify

Tomás runs the whole cycle on a lab copy of the portal. Detect: the lab database stores unsalted SHA-256 hashes. Fix: the application is changed to compute scrypt with policy parameters at the next successful login and to replace the old hash, so users need not reset. Verify: he logs in with a synthetic account, checks that the stored value now has the scrypt format and that a wrong password fails. He records each step as evidence. The same plan then goes to the development team for the real portal, through their normal release process.

Worked example

Tomás confirms the RFC 7914 vector, shows distinct salted hashes for identical passwords and documents an upgrade-at-login fix in the lab.

Synthetic case. Users, passwords and the portal copy are synthetic; RFC 7914 and RFC 9106 are real.

Errors and limits

Lab parameters are deliberately small; production needs policy-set cost. Upgrade-at-login leaves dormant accounts on old hashes until handled separately.

Exercises

Synthesis

Password storage needs slow, salted, standard functions, verified against vectors and rolled out through a detect-fix-verify cycle.

Continue studying — chapter 17 of 18

← Chapter 16 (draft) · Course chapter index · Chapter 18 (draft) →