scrypt Password Hash And Verify
Hash passwords with scrypt and a per-user salt, then verify them with a constant-time comparison.
Code
import hashlib
import hmac
import os
N = 2 ** 14
R = 8
P = 1
KEY_LEN = 32
SALT_LEN = 16
def hash_password(password: str) -> str:
salt = os.urandom(SALT_LEN)
digest = hashlib.scrypt(password.encode('utf-8'), salt=salt, n=N, r=R, p=P, dklen=KEY_LEN)
return f'scrypt${N}${R}${P}${salt.hex()}${digest.hex()}'
def verify_password(password: str, encoded: str) -> bool:
parts = encoded.split('$')
if len(parts) != 5 or parts[0] != 'scrypt':
return False
_, n, r, p, rest = parts
salt_hex, digest_hex = rest[:SALT_LEN * 2], rest[SALT_LEN * 2:]
expected = bytes.fromhex(digest_hex)
digest = hashlib.scrypt(password.encode('utf-8'), salt=bytes.fromhex(salt_hex),
n=int(n), r=int(r), p=int(p), dklen=len(expected))
return hmac.compare_digest(digest, expected)Report a problem with this exampleOpens a pre-filled issue on GitHub.