from typing import Optional import bcrypt, binascii, hashlib, secrets def hash_password(password: str) -> str: return bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt(rounds=12)).decode("utf-8") def verify_password(password: str, hashed: str) -> bool: try: return bcrypt.checkpw(password.encode("utf-8"), hashed.encode("utf-8")) except Exception: return False def verify_legacy_password(password: str, salt_hex: Optional[str], hash_hex: Optional[str]) -> bool: if not salt_hex or not hash_hex: return False salt = binascii.unhexlify(salt_hex.encode()) dk = hashlib.pbkdf2_hmac("sha256", password.encode("utf-8"), salt, 200_000) return secrets.compare_digest(binascii.hexlify(dk).decode(), hash_hex)