← Module 1: Secure Software Architecture
Inquiry Question 1: How are secure systems designed?
Describe how hashing and salting protect stored passwords, and identify weaknesses in storing passwords in plain text or with reversible encryption
A focused answer to the HSC Software Engineering Module 1 dot point on password hashing. Why passwords are hashed and not encrypted, salting, slow hash functions like bcrypt, the worked example, and the traps markers look for.
Have a quick question? Jump to the Q&A page
What this dot point is asking
NESA wants you to explain why secure systems store passwords as hashes (not as encrypted text or plain text), describe what salting adds, and identify the weaknesses in each weaker storage approach.
The answer
Why not plain text
If passwords are stored as plain text, any database breach hands every password to the attacker. Worse, because people reuse passwords across sites, a breach of one site compromises accounts on many other sites.
Why not just encryption
Encryption is reversible. If the password column is encrypted with AES, the encryption key must also be on the server (or accessible to it) to verify logins. If the attacker steals the database, they usually also steal the key. Plain text and encrypted-with-known-key storage are equally bad.
Hashing
A hash function takes any input and produces a fixed-length output. Good cryptographic hash functions are:
- One-way: you cannot recover the input from the hash.
- Deterministic: the same input always produces the same hash.
- Collision-resistant: two different inputs almost never produce the same hash.
When a user signs up, the server hashes the password and stores only the hash. When they log in, the server hashes the submitted password and compares hashes. The password itself is never stored.
Salting
A salt is a random string (typically 16+ bytes) generated uniquely per user and combined with the password before hashing. Salting defeats two precomputed-attack categories:
- Rainbow tables: precomputed hash-to-password lookups for common passwords. With a unique salt per user, every user's effective password is different, and a single rainbow table cannot cover them all.
- Hash sharing: two users with the same password no longer have the same hash, so an attacker cannot see which accounts share a password.
The salt is stored alongside the hash. It does not need to be secret - its job is to be unique.
Slow hash functions
General-purpose hashes like SHA-256 are too fast: a GPU can compute billions per second, so brute-forcing weak passwords is cheap. Password storage uses deliberately slow hash functions:
- bcrypt: a tunable work factor lets you control how slow it is.
- scrypt: also memory-hard, defeating GPU and ASIC attacks.
- Argon2: the modern winner of the Password Hashing Competition.
Each takes hundreds of milliseconds per hash by design - fast enough for login (one hash) but billions of times too slow for brute force attacks.
Worked code
Python with the bcrypt library:
import bcrypt
# At signup:
password = b"correct horse battery staple"
salt = bcrypt.gensalt(rounds=12)
hashed = bcrypt.hashpw(password, salt)
# Store only `hashed` in the database.
# At login:
submitted = b"correct horse battery staple"
if bcrypt.checkpw(submitted, hashed):
print("Login OK")
else:
print("Wrong password")
bcrypt produces a hash that contains the algorithm, work factor, and salt all packed together, so no separate salt column is needed.
Past exam questions, worked
Real questions from past NESA papers on this dot point, with our answer explainer.
2024 HSC4 marksExplain why passwords should be stored as salted hashes rather than encrypted, and describe one attack that salting defends against.Show worked answer →
Hashing is one-way; encryption is two-way. A hash takes a password and produces a fixed-length digest from which the original cannot be recovered. Encryption is reversible if you have the key. If the password database is encrypted and the key leaks, every password is exposed.
With hashing, even if the database is stolen, the attacker cannot recover the original passwords - they can only check guesses by hashing them and comparing.
A salt is a unique random string added to each password before hashing. It defends against rainbow table attacks. A rainbow table is a precomputed mapping from common passwords to their hash values. Without a salt, every user with the password "password123" has the same hash, and the attacker only needs to look it up once.
With a unique salt per user, the same password produces a different hash for every user. The attacker has to attack each account individually, which is millions of times slower. The salt is stored alongside the hash; it is not secret, but it forces per-user attack work.
Markers reward the hashing vs encryption distinction, salt as defending against rainbow tables, and the explicit point that the salt is unique per user.
Related dot points
- Compare symmetric and asymmetric encryption, and describe their roles in securing data in transit and at rest
A focused answer to the HSC Software Engineering Module 1 dot point on encryption. Symmetric (AES) versus asymmetric (RSA), where each is used, how HTTPS combines them, the worked example, and the traps markers look for.
- Explain the role of authentication and authorisation in restricting access to a system, and identify common implementation methods including multi-factor authentication and role-based access control
A focused answer to the HSC Software Engineering Module 1 dot point on authentication and authorisation. The difference between the two, multi-factor authentication, role-based access control, the worked SaaS-app example, and the traps markers look for.
- Apply input validation, sanitisation and output encoding to defend against injection attacks
A focused answer to the HSC Software Engineering Module 1 dot point on input validation. Allow-list vs deny-list, sanitisation, output encoding, parameterised queries, the worked SQL injection example, and the traps markers look for.