◇ OpenCyber Academy
Bachelor's · Chapter 9 · English

Chapter 9 — Data and databases

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 9 — Data and databases

Lesson map

Lesson 09 published. Map, example, EX025.

flowchart TD
  N0["Learning outcomes"]
  N1["9.1 Password storage"]
  N2["Lab — Salted password hashing"]
  N3["9.2 Reading the run"]
  N4["9.3 Field-level choices"]
  N5["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5
  N5 --> EX["Worked example"]
  EX --> Q["Exercise EX025"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["9.1 Password storage"]
  N2["Lab — Salted password hashing"]
  N3["9.2 Reading the run"]
  N4["9.3 Field-level choices"]
  N5["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> Q["EX025"]
[Learning outcomes]
    |
    v
[9.1 Password storage]
    |
    v
[Lab — Salted password hashing]
    |
    v
[9.2 Reading the run]
    |
    v
[9.3 Field-level choices]
    |
    v
[Synthesis]
    |
    v
[Worked example] --> [Exercise EX025]

Learning outcomes

You will (1) store passwords with salted, slow hashing; (2) explain why salts and work factors matter; (3) choose field-level protections in a database.

9.1 Password storage

Tidewell's old portal stored passwords with plain SHA-256, which Priya explains is unsafe: SHA-256 is fast, so an attacker with a stolen table can test billions of guesses per second, and identical passwords produce identical hashes. A proper scheme adds a unique random salt per user and uses a deliberately slow function. RFC 9106 specifies Argon2id, the preferred choice; PBKDF2, available in Python's hashlib, is an older fallback that needs a high iteration count. The lab demonstrates salting with PBKDF2 because it is in the standard library.

Lab — Salted password hashing

"""Salted password hashing with hashlib.pbkdf2_hmac on synthetic passwords (prefer Argon2id, RFC 9106)."""
import hashlib, hmac
def h(pw, salt, n=600_000):
    return hashlib.pbkdf2_hmac("sha256", pw.encode(), salt, n).hex()

def main():
    s1, s2 = bytes.fromhex("a1" * 16), bytes.fromhex("b2" * 16)  # fixed demo salts for reproducible output
    a, b = h("correct horse 42", s1), h("correct horse 42", s2)
    print("same password, different salts differ:", a != b)
    print("stored:", a[:24], "...")
    print("login with right password:", hmac.compare_digest(a, h("correct horse 42", s1)))
    print("login with wrong password:", hmac.compare_digest(a, h("correct horse 43", s1)))

if __name__ == "__main__":
    main()

Run with python3 lab_pbkdf2.py. Verified output:

same password, different salts differ: True
stored: c96866459ba12d6a7bc6285d ...
login with right password: True
login with wrong password: False

9.2 Reading the run

The same password with two different salts produces different stored values, so an attacker cannot see which patrons share a password or use precomputed tables. Logging in with the right password recomputes the same value and compare_digest returns True; a one-character change returns False. The fixed demonstration salts exist only to make the output repeatable; real salts come from secrets.token_bytes. The 600,000 iterations slow each guess. Priya recommends migrating to Argon2id, rehashing each password at the patron's next successful login.

9.3 Field-level choices

Beyond passwords, Priya classifies database fields: names and addresses are encrypted at the field level with keys from the consortium's key service; loan history older than ninety days is deleted, following the privacy principle of keeping only what is needed; and patron card numbers are tokenised for reporting systems. She records that deleting old data is often the strongest protection, since data that does not exist cannot leak. Grace agrees and schedules the retention change after board approval. The policy is published for patrons.

Worked example

Priya replaces plain SHA-256 with salted slow hashing, plans migration to Argon2id at next login, encrypts personal fields and deletes loan history after ninety days.

Synthetic case. Tidewell's database is invented; RFC 9106 is real.

Errors and limits

Slow hashing does not save very weak passwords. Encryption keys stored beside the database offer little protection.

Exercises

Synthesis

Salted, slow password hashing, field encryption and data minimisation protect patron data in databases.

Continue studying — chapter 09 of 40

← Chapter 08 (draft) · Course chapter index · Chapter 10 (draft) →