From c85c68f8596179c23161df2a1c8a9e3ba283d567 Mon Sep 17 00:00:00 2001 From: Joachim Hummel Date: Thu, 13 Nov 2025 13:18:22 +0000 Subject: [PATCH] refactor: update hash_password and verify_password to use algorithm interface --- salt.py | 34 +++++++++------------------------- tests/test_hashing.py | 6 ++++++ 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/salt.py b/salt.py index 6dd0f68..20a4d91 100644 --- a/salt.py +++ b/salt.py @@ -19,22 +19,15 @@ DEFAULT_ITERATIONS = int(os.environ.get("PBKDF2_ITERATIONS", "200000")) def hash_password( password: str, *, + algorithm: str = "pbkdf2", iterations: int | None = None, salt_bytes: int = DEFAULT_SALT_BYTES, ) -> tuple[str, str]: """Return a base64 encoded salt and hash for ``password``.""" - iterations = iterations or DEFAULT_ITERATIONS - salt = os.urandom(salt_bytes) - derived = hashlib.pbkdf2_hmac( - "sha256", - password.encode("utf-8"), - salt, - iterations, - ) - return ( - base64.b64encode(salt).decode("utf-8"), - base64.b64encode(derived).decode("utf-8"), - ) + from algorithms import get_algorithm + + algo = get_algorithm(algorithm) + return algo.hash(password, iterations=iterations, salt_bytes=salt_bytes) def verify_password( @@ -42,23 +35,14 @@ def verify_password( salt_b64: str, hash_b64: str, *, + algorithm: str = "pbkdf2", iterations: int | None = None, ) -> bool: """Validate ``password`` against the provided base64 salt + hash pair.""" - iterations = iterations or DEFAULT_ITERATIONS - try: - salt = base64.b64decode(salt_b64, validate=True) - stored_hash = base64.b64decode(hash_b64, validate=True) - except (binascii.Error, ValueError): - return False + from algorithms import get_algorithm - derived = hashlib.pbkdf2_hmac( - "sha256", - password.encode("utf-8"), - salt, - iterations, - ) - return hmac.compare_digest(derived, stored_hash) + algo = get_algorithm(algorithm) + return algo.verify(password, salt_b64, hash_b64, iterations=iterations) def _build_parser() -> argparse.ArgumentParser: diff --git a/tests/test_hashing.py b/tests/test_hashing.py index 5498e4e..27f3bb2 100644 --- a/tests/test_hashing.py +++ b/tests/test_hashing.py @@ -18,3 +18,9 @@ def test_hash_password_returns_base64() -> None: def test_verify_password_handles_invalid_base64() -> None: assert verify_password("secret", "**invalid**", "???") is False + + +def test_hash_password_with_algorithm_parameter(): + """Verify hash_password accepts algorithm parameter.""" + salt, hashed = hash_password("test", algorithm="pbkdf2") + assert verify_password("test", salt, hashed, algorithm="pbkdf2")