

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Still calibrating
click for more info
Not enough gems
Cost: 6 gems
1: Encrypting Data at Rest
incomplete
2: Key Management and Rotation
incomplete
3: Password KDFs
incomplete
4: Salts
incomplete
5: Argon2 Parameters
incomplete
6: Encrypted Files
incomplete
7: Secure Database Practices
incomplete
8: Personally Identifiable Information
incomplete
9: Financial Data
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
As we all know, passwords should never be stored in plaintext... but even hashing them isn't always enough.
If attackers steal your password hashes, they can test guesses offline on their own hardware with no rate limit. A fast general-purpose hash function like SHA-256 lets them rip through candidates, making SHA-256 a terrible password-storage choice.
Click to play video
A password key derivation function is designed to be expensive. For example, Argon2id consumes both CPU time and memory, making large batches of offline guesses much more costly.
import argon2 from "argon2";
export async function hashPassword(password: string): Promise<string> {
return argon2.hash(password, {
type: argon2.argon2id,
memoryCost: 19 * 1024,
timeCost: 2,
parallelism: 1,
});
}
Suppose your app already has users whose passwords are stored as 64-character SHA-256 hashes. Ruh-roh. Simply adding an Argon2-only verifier would lock them out!
You'll need to verify both formats during the migration, but create only Argon2id hashes for new or changed passwords:
// this regex matches exactly 64 hex characters
// meaning (in our system) it's a legacy SHA-256 hash
if (/^[a-f0-9]{64}$/i.test(passwordHash)) {
return verifyLegacyPassword(password, passwordHash);
}
// this string starts with "$argon2id$" meaning
// the password was hashed with Argon2id
if (passwordHash.startsWith("$argon2id$")) {
return argon2.verify(passwordHash, password);
}
return false;
Bearly Secure stores passwords with fast SHA-256 hashes. Adopt Argon2id for every new or changed password without breaking existing legacy accounts.
Run and submit the CLI tests from the project root.