Files
CTXD/app/src/ctxd/auth_password.py
T

40 lines
1.1 KiB
Python
Raw Normal View History

"""Password hashing for CTXD user accounts (stdlib only)."""
from __future__ import annotations
import hashlib
import secrets
PBKDF2_ITERATIONS = 600_000
SCHEME = "pbkdf2_sha256"
def hash_password(password: str) -> str:
if not password:
raise ValueError("password required")
salt = secrets.token_hex(16)
digest = hashlib.pbkdf2_hmac(
"sha256",
password.encode("utf-8"),
salt.encode("utf-8"),
PBKDF2_ITERATIONS,
)
return f"{SCHEME}${PBKDF2_ITERATIONS}${salt}${digest.hex()}"
def verify_password(password: str, token_hash: str | None) -> bool:
if not password or not token_hash:
return False
try:
scheme, iters_s, salt, expected_hex = token_hash.split("$", 3)
if scheme != SCHEME:
return False
digest = hashlib.pbkdf2_hmac(
"sha256",
password.encode("utf-8"),
salt.encode("utf-8"),
int(iters_s),
)
return secrets.compare_digest(digest.hex(), expected_hex)
except (ValueError, TypeError):
return False