Storing passwords safely

A system that stores passwords must assume its database will eventually leak. Never store passwords in plain text or encrypted with a key kept next to the data. Store only a verifier that can check a guess but is expensive to reverse.

Python
import hashlib
import hmac
import os

ITERATIONS = 600_000


def hash_password(password, salt):
    return hashlib.pbkdf2_hmac("sha256", password.encode(), salt, ITERATIONS)


def verify(password, salt, stored):
    return hmac.compare_digest(hash_password(password, salt), stored)


salt_a = os.urandom(16)
salt_b = os.urandom(16)
stored = hash_password("correct horse", salt_a)
print(verify("correct horse", salt_a, stored))
print(verify("wrong guess", salt_a, stored))
print(hash_password("correct horse", salt_a) == hash_password("correct horse", salt_b))
print(len(salt_a), len(stored))
Read the full lesson