"""Password hashing and session helpers. Uses stdlib PBKDF2 so no native build dependencies are required. """ from __future__ import annotations import hashlib import hmac import secrets _ALGO = "sha256" _ITERATIONS = 240_000 def hash_password(password: str) -> str: salt = secrets.token_hex(16) digest = hashlib.pbkdf2_hmac( _ALGO, password.encode(), bytes.fromhex(salt), _ITERATIONS ).hex() return f"pbkdf2_{_ALGO}${_ITERATIONS}${salt}${digest}" def verify_password(password: str, stored: str) -> bool: try: scheme, iterations, salt, digest = stored.split("$") if not scheme.startswith("pbkdf2_"): return False algo = scheme.split("_", 1)[1] expected = hashlib.pbkdf2_hmac( algo, password.encode(), bytes.fromhex(salt), int(iterations) ).hex() return hmac.compare_digest(expected, digest) except (ValueError, TypeError): return False