CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-argon2-cffi

Argon2 password hashing algorithm for Python with secure defaults and multiple variants

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

exceptions.mddocs/

Exception Handling

Comprehensive exception hierarchy for different error conditions in Argon2 operations, providing specific error types for verification failures, hashing errors, invalid parameters, and platform-specific limitations.

Capabilities

Base Exception

Root exception class for all Argon2-related errors.

class Argon2Error(Exception):
    """
    Superclass of all argon2 exceptions.
    
    Never thrown directly - used as base class for specific error types.
    Catch this to handle any Argon2-related error.
    """

Usage Example

from argon2 import PasswordHasher
from argon2.exceptions import Argon2Error

ph = PasswordHasher()

try:
    result = ph.hash("password")
    ph.verify(result, "password")
except Argon2Error as e:
    print(f"Argon2 operation failed: {e}")

Verification Errors

Exceptions raised during password verification operations.

class VerificationError(Argon2Error):
    """
    Verification failed for unspecified reasons.
    
    Base class for verification-related errors. The original error
    message from Argon2 C library is available in args[0].
    """

class VerifyMismatchError(VerificationError):
    """
    The secret does not match the hash.
    
    Raised when password verification fails because the provided
    password does not match the stored hash. This is the most
    common verification error during normal operation.
    """

Usage Example

from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError, VerificationError

ph = PasswordHasher()
stored_hash = ph.hash("correct_password")

# Handle specific verification failures
try:
    ph.verify(stored_hash, "wrong_password")
except VerifyMismatchError:
    print("Invalid password - access denied")
except VerificationError as e:
    print(f"Verification failed due to error: {e}")

# Handle all verification errors together
try:
    ph.verify(stored_hash, user_input)
    print("Login successful")
except VerificationError:
    print("Login failed")

Hashing Errors

Exception raised when hash generation fails.

class HashingError(Argon2Error):
    """
    Raised if hashing failed.
    
    Indicates that the Argon2 hashing operation could not be completed.
    The original error message from Argon2 C library is available in args[0].
    
    Common causes:
    - Invalid parameters (e.g., memory cost too high)
    - System resource limitations
    - Memory allocation failures
    """

Usage Example

from argon2 import PasswordHasher
from argon2.exceptions import HashingError

# Attempt hashing with potentially problematic parameters
try:
    ph = PasswordHasher(
        memory_cost=999999999,  # Excessive memory requirement
        time_cost=1000,         # Very high time cost
    )
    hash_result = ph.hash("password")
except HashingError as e:
    print(f"Hashing failed: {e}")
    # Fall back to more conservative parameters
    ph_safe = PasswordHasher()  # Use defaults
    hash_result = ph_safe.hash("password")

Hash Format Errors

Exception raised for invalid hash formats.

class InvalidHashError(ValueError):
    """
    Raised if the hash is invalid before passing it to Argon2.
    
    Indicates that the hash string format is so malformed that
    it cannot be processed by the Argon2 library. This includes:
    - Incorrect hash string structure
    - Missing required components
    - Invalid encoding
    """

# Deprecated alias (still available for compatibility)
InvalidHash = InvalidHashError
"""
Deprecated alias for InvalidHashError.
Use InvalidHashError instead.
"""

Usage Example

from argon2 import PasswordHasher
from argon2.exceptions import InvalidHashError

ph = PasswordHasher()

invalid_hashes = [
    "not_a_hash_at_all",
    "$argon2id$invalid$format",
    "",
    "$argon2id$v=19$m=65536,t=3,p=4",  # Missing salt and hash
]

for bad_hash in invalid_hashes:
    try:
        ph.verify(bad_hash, "password")
    except InvalidHashError:
        print(f"Invalid hash format: {bad_hash}")

Platform Limitations

Exception raised when parameters are not supported on the current platform.

class UnsupportedParametersError(ValueError):
    """
    Raised if the current platform does not support the parameters.
    
    Examples:
    - WebAssembly environments require parallelism=1
    - Memory-constrained systems may not support high memory costs
    - Some embedded platforms have threading limitations
    """

Usage Example

from argon2 import PasswordHasher
from argon2.exceptions import UnsupportedParametersError

try:
    # This may fail in WebAssembly environments
    ph = PasswordHasher(parallelism=8)
except UnsupportedParametersError as e:
    print(f"Parameters not supported on this platform: {e}")
    # Fall back to platform-compatible settings
    ph = PasswordHasher(parallelism=1)

# Alternative: Use platform-aware defaults
from argon2.profiles import get_default_parameters
default_params = get_default_parameters()  # Automatically adjusts for platform
ph = PasswordHasher.from_parameters(default_params)

Error Handling Patterns

Comprehensive Error Handling

Handle all possible Argon2 errors with appropriate fallbacks:

from argon2 import PasswordHasher
from argon2.exceptions import (
    VerifyMismatchError,
    VerificationError,
    HashingError,
    InvalidHashError,
    UnsupportedParametersError,
    Argon2Error
)

def safe_hash_password(password: str) -> str:
    """Hash password with error handling and fallbacks."""
    try:
        ph = PasswordHasher()
        return ph.hash(password)
    except UnsupportedParametersError:
        # Fall back to platform-compatible parameters
        ph = PasswordHasher(parallelism=1)
        return ph.hash(password)
    except HashingError as e:
        # Log error and use more conservative parameters
        print(f"Hashing failed, trying conservative settings: {e}")
        ph = PasswordHasher(memory_cost=32768, time_cost=2)
        return ph.hash(password)

def safe_verify_password(hash_str: str, password: str) -> bool:
    """Verify password with comprehensive error handling."""
    try:
        ph = PasswordHasher()
        ph.verify(hash_str, password)
        return True
    except VerifyMismatchError:
        # Normal case - wrong password
        return False
    except InvalidHashError:
        # Hash is corrupted/invalid - treat as verification failure
        print("Warning: Invalid hash format detected")
        return False
    except VerificationError as e:
        # Other verification issues - log but treat as failure
        print(f"Verification error: {e}")
        return False

Login System Integration

Typical integration pattern for authentication systems:

from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError, Argon2Error

def authenticate_user(username: str, password: str) -> bool:
    """Authenticate user with proper error handling."""
    # Retrieve stored hash from database
    stored_hash = get_user_hash(username)
    if not stored_hash:
        return False
    
    ph = PasswordHasher()
    
    try:
        # Verify password
        ph.verify(stored_hash, password)
        
        # Check if hash needs updating
        if ph.check_needs_rehash(stored_hash):
            new_hash = ph.hash(password)
            update_user_hash(username, new_hash)
            print(f"Updated password hash for user: {username}")
        
        return True
        
    except VerifyMismatchError:
        # Wrong password - normal case
        return False
    except Argon2Error as e:
        # Any other Argon2 error - log and deny access
        print(f"Authentication error for {username}: {e}")
        return False

Parameter Validation

Validate parameters before creating PasswordHasher instances:

from argon2 import PasswordHasher, Parameters
from argon2.exceptions import UnsupportedParametersError
from argon2._utils import validate_params_for_platform

def create_secure_hasher(
    time_cost: int = 3,
    memory_cost: int = 65536,
    parallelism: int = 4
) -> PasswordHasher:
    """Create hasher with parameter validation."""
    
    # Create parameters object for validation
    params = Parameters(
        type=Type.ID,
        version=19,
        salt_len=16,
        hash_len=32,
        time_cost=time_cost,
        memory_cost=memory_cost,
        parallelism=parallelism,
    )
    
    try:
        # Validate parameters for current platform
        validate_params_for_platform(params)
        return PasswordHasher.from_parameters(params)
    except UnsupportedParametersError as e:
        print(f"Parameters not supported: {e}")
        # Return hasher with platform defaults
        from argon2.profiles import get_default_parameters
        return PasswordHasher.from_parameters(get_default_parameters())

Install with Tessl CLI

npx tessl i tessl/pypi-argon2-cffi

docs

exceptions.md

index.md

low-level.md

password-hasher.md

profiles.md

tile.json