Password hashing done right

Passwords are never stored. Hashes are. A good hash is slow enough that brute force is expensive, unique per user so the same password produces different hashes, and forward-compatible so you can crank the cost later without breaking existing accounts. PBKDF2-HMAC-SHA256 gives us all three.

user_auth.py
python
def _hash_password(self, password: str, salt: str) -> str:
    return hashlib.pbkdf2_hmac(
        "sha256",
        password.encode(),
        salt.encode(),
        PBKDF2_ITERATIONS,  # 100_000
    ).hex()

def _generate_salt(self) -> str:
    return secrets.token_hex(16)  # 32 hex chars, 128 bits of entropy

Three things matter: the algorithm, a unique per-user salt generated with a cryptographically secure RNG, and an iteration count that makes each hash take real CPU time.

Flashcards: Flashcards

Loading practice…

Quiz: Quiz

Loading practice…