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))