from argon2 import PasswordHasher from argon2.exceptions import VerifyMismatchError import secrets
def verify_password(password: str, stored_bcrypt_hash: str) -> bool: """Verify password using bcrypt (internal salt) and external pepper.""" # Step 1: Retrieve the stored bcrypt hash stored_bcrypt_bytes = stored_bcrypt_hash.encode('utf-8') authentication unique keys and salts
# Store the raw salted hash AND the peppered hash? No. # Actually, store the raw salted hash. Apply pepper only during verification. # Why? Because bcrypt needs the raw hash to verify. from argon2 import PasswordHasher from argon2
While salts aren't necessarily "secret" (just unique), the pepper must remain hidden. stored_bcrypt_hash: str) ->
If a hacker tries to change the cookie data, the hash will no longer match the secret keys stored on the server. The server will detect the tampering and immediately reject the session, logging the hacker out.