Course outline · 0% complete

0/29 lessons0%

Course overview →

Passwords Done Right

lesson 7-1 · ~12 min · 20/29

Quiz

Warm-up from lesson 6-3. Why must the login query use db.all("... WHERE email = ?", [email]) instead of gluing email into the SQL string?

Rule zero: never store the password

If your users table contains real passwords and the database ever leaks (it happens to giant companies), every account is instantly lost, including accounts on other sites where users reused the password.

So servers store a hash instead: the output of a one-way function. A hash function like SHA-256:

  • always gives the same output for the same input,
  • changes completely when the input changes by one character,
  • cannot be run backward: the hash does not reveal the password.

Login then works without ever storing the secret: hash what the user typed, compare hashes. Run it below, the long hex string is what a database would hold.

Code exercise · javascript

Run this. Node's built-in crypto module computes SHA-256. Same input, same hash. Different input, a completely different hash.

Salt, and why bcrypt exists

Plain SHA-256 has two problems as a password hash:

  1. Attackers precomputed hashes for millions of common passwords (rainbow tables). If your table stores sha256("hunter2"), a lookup cracks it instantly. The fix is a salt: a random string stored next to each user, mixed into the hash. Now sha256(salt + password) differs per user, and precomputed tables are useless.
  2. SHA-256 is fast, so attackers can guess billions per second. Real password hashers (bcrypt, argon2) are deliberately slow and salted for you:
const bcrypt = require("bcrypt");
const hash = await bcrypt.hash(password, 12); // store this
const ok = await bcrypt.compare(candidate, hash); // login check

In production: bcrypt or argon2, full stop. The exercise below uses sha256(salt + password) only so you can see the salted-verify mechanic with your own eyes.

Code exercise · javascript

Your turn. Implement checkPassword(user, candidate): hash user.salt + candidate with sha256 and compare it to user.passwordHash. Return the boolean. The stored hash was made from the salt plus "hunter2".

Quiz

A company's database leaks, and it stored bcrypt password hashes. Why are its users far better off than if it had stored plain SHA-256 hashes?