Argon2 password hashing algorithm for Python with secure defaults and multiple variants
npx @tessl/cli install tessl/pypi-argon2-cffi@25.1.0Python bindings for the Argon2 password hashing algorithm, winner of the Password Hashing Competition. Provides secure password hashing with industry-standard defaults, supporting all three Argon2 variants (Argon2i, Argon2d, Argon2id) with configurable memory usage, parallelism, and time costs.
pip install argon2-cffiimport argon2Common usage pattern:
from argon2 import PasswordHasherAccess to all public components:
from argon2 import (
PasswordHasher,
Type,
Parameters,
extract_parameters,
exceptions,
low_level,
profiles
)from argon2 import PasswordHasher
# Create a password hasher with secure defaults
ph = PasswordHasher()
# Hash a password
password = "supersecret"
hash = ph.hash(password)
print(hash) # $argon2id$v=19$m=65536,t=3,p=4$...
# Verify a password
try:
ph.verify(hash, password)
print("Password is correct!")
except argon2.exceptions.VerifyMismatchError:
print("Password is wrong!")
# Check if hash needs rehashing (due to changed parameters)
if ph.check_needs_rehash(hash):
new_hash = ph.hash(password)
# Update stored hash in databaseArgon2-CFFI provides a layered architecture for different use cases:
PasswordHasher): Simple, secure API with sensible defaults for typical password hashing needsThe library automatically handles salt generation, constant-time verification to prevent timing attacks, and parameter validation for the current platform.
High-level password hashing with the PasswordHasher class, providing secure defaults and convenient methods for common password operations including hashing, verification, and rehash detection.
class PasswordHasher:
def __init__(
self,
time_cost: int = DEFAULT_TIME_COST,
memory_cost: int = DEFAULT_MEMORY_COST,
parallelism: int = DEFAULT_PARALLELISM,
hash_len: int = DEFAULT_HASH_LENGTH,
salt_len: int = DEFAULT_RANDOM_SALT_LENGTH,
encoding: str = "utf-8",
type: Type = Type.ID,
): ...
def hash(self, password: str | bytes, *, salt: bytes | None = None) -> str: ...
def verify(self, hash: str | bytes, password: str | bytes) -> Literal[True]: ...
def check_needs_rehash(self, hash: str | bytes) -> bool: ...Direct access to Argon2 C library functions for advanced users who need fine-grained control over hashing parameters, raw hash outputs, or custom implementations.
def hash_secret(
secret: bytes,
salt: bytes,
time_cost: int,
memory_cost: int,
parallelism: int,
hash_len: int,
type: Type,
version: int = ARGON2_VERSION,
) -> bytes: ...
def verify_secret(hash: bytes, secret: bytes, type: Type) -> Literal[True]: ...Comprehensive exception hierarchy for different error conditions including verification failures, hashing errors, invalid parameters, and platform-specific limitations.
class Argon2Error(Exception): ...
class VerificationError(Argon2Error): ...
class VerifyMismatchError(VerificationError): ...
class HashingError(Argon2Error): ...
class InvalidHashError(ValueError): ...
class UnsupportedParametersError(ValueError): ...Predefined parameter configurations following RFC 9106 recommendations and utilities for parameter management, extraction, and platform validation.
class Parameters:
type: Type
version: int
salt_len: int
hash_len: int
time_cost: int
memory_cost: int
parallelism: int
def get_default_parameters() -> Parameters: ...
def extract_parameters(hash: str) -> Parameters: ...Deprecated functions maintained for backward compatibility with older code. Use PasswordHasher for new applications.
def hash_password(
password: bytes,
salt: bytes | None = None,
time_cost: int = DEFAULT_TIME_COST,
memory_cost: int = DEFAULT_MEMORY_COST,
parallelism: int = DEFAULT_PARALLELISM,
hash_len: int = DEFAULT_HASH_LENGTH,
type: Type = Type.I,
) -> bytes: ...
def hash_password_raw(
password: bytes,
salt: bytes | None = None,
time_cost: int = DEFAULT_TIME_COST,
memory_cost: int = DEFAULT_MEMORY_COST,
parallelism: int = DEFAULT_PARALLELISM,
hash_len: int = DEFAULT_HASH_LENGTH,
type: Type = Type.I,
) -> bytes: ...
def verify_password(hash: bytes, password: bytes, type: Type = Type.I) -> Literal[True]: ...from typing import Literal
class Type(Enum):
"""Argon2 algorithm variants"""
D = ... # Argon2d (data-dependent)
I = ... # Argon2i (data-independent)
ID = ... # Argon2id (hybrid)
# Default configuration constants
DEFAULT_TIME_COST: int
DEFAULT_MEMORY_COST: int
DEFAULT_PARALLELISM: int
DEFAULT_HASH_LENGTH: int
DEFAULT_RANDOM_SALT_LENGTH: int