24 lines
830 B
Python
24 lines
830 B
Python
import hashlib
|
|||
|
|
import secrets
|
||
|
|
|
||
|
|
|
||
|
|
def hash_password(password: str, iterations: int = 200_000) -> str:
|
||
|
|
salt = secrets.token_bytes(16)
|
||
|
|
digest = hashlib.pbkdf2_hmac("sha256", password.encode("utf-8"), salt, iterations)
|
||
|
|
return f"pbkdf2_sha256${iterations}${salt.hex()}${digest.hex()}"
|
||
|
|
|
||
|
|
|
||
|
|
def verify_password(password: str, password_hash: str) -> bool:
|
||
|
|
try:
|
||
|
|
algorithm, rounds_raw, salt_hex, digest_hex = password_hash.split("$", 3)
|
||
|
|
if algorithm != "pbkdf2_sha256":
|
||
|
|
return False
|
||
|
|
rounds = int(rounds_raw)
|
||
|
|
salt = bytes.fromhex(salt_hex)
|
||
|
|
expected = bytes.fromhex(digest_hex)
|
||
|
|
except (ValueError, TypeError):
|
||
|
|
return False
|
||
|
|
|
||
|
|
candidate = hashlib.pbkdf2_hmac("sha256", password.encode("utf-8"), salt, rounds)
|
||
|
|
return secrets.compare_digest(candidate, expected)
|