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

profiles.mddocs/

Parameter Profiles

Predefined parameter configurations following RFC 9106 recommendations and utilities for parameter management, extraction, and platform validation.

Capabilities

Parameter Management

Container class for Argon2 hash parameters with all necessary configuration options.

@dataclass
class Parameters:
    """
    Argon2 hash parameters.
    
    Contains all parameters needed to configure Argon2 hashing
    including algorithm variant, memory usage, time cost, and output formats.
    """
    
    type: Type           # Hash type (I, D, or ID)
    version: int        # Argon2 version number
    salt_len: int       # Length of salt in bytes
    hash_len: int       # Length of hash output in bytes
    time_cost: int      # Time cost in iterations
    memory_cost: int    # Memory cost in kibibytes
    parallelism: int    # Number of parallel threads

Usage Example

from argon2 import Parameters, Type, PasswordHasher

# Create custom parameters
custom_params = Parameters(
    type=Type.ID,
    version=19,
    salt_len=16,
    hash_len=32,
    time_cost=4,
    memory_cost=131072,  # 128 MiB
    parallelism=2
)

# Use with PasswordHasher
ph = PasswordHasher.from_parameters(custom_params)

Parameter Extraction

Extract parameters from existing hash strings to understand their configuration.

def extract_parameters(hash: str) -> Parameters:
    """
    Extract parameters from an encoded hash string.
    
    Parses an Argon2 hash string and returns a Parameters object
    containing all the configuration used to create that hash.
    
    Args:
        hash: Encoded Argon2 hash string (e.g., from PasswordHasher.hash())
    
    Returns:
        Parameters object with extracted configuration
    
    Raises:
        argon2.exceptions.InvalidHashError: If hash format is invalid
    """

Usage Example

from argon2 import PasswordHasher, extract_parameters

# Create a hash
ph = PasswordHasher()
hash_string = ph.hash("password")
print(hash_string)
# $argon2id$v=19$m=65536,t=3,p=4$base64salt$base64hash

# Extract parameters from the hash
params = extract_parameters(hash_string)
print(f"Type: {params.type}")           # Type.ID
print(f"Memory: {params.memory_cost}")  # 65536
print(f"Time: {params.time_cost}")      # 3
print(f"Parallelism: {params.parallelism}")  # 4

# Create hasher with same parameters
ph_same = PasswordHasher.from_parameters(params)

Platform-Aware Defaults

Get default parameters that are compatible with the current platform.

def get_default_parameters() -> Parameters:
    """
    Create default parameters for current platform.
    
    Returns platform-compatible parameters based on RFC 9106 low-memory
    profile, with automatic adjustments for platform limitations
    (e.g., parallelism=1 in WebAssembly environments).
    
    Returns:
        Default Parameters object for current platform
    """

Usage Example

from argon2.profiles import get_default_parameters
from argon2 import PasswordHasher

# Get platform-aware defaults
default_params = get_default_parameters()
print(f"Default parameters for this platform:")
print(f"  Memory: {default_params.memory_cost} KiB")
print(f"  Time: {default_params.time_cost}")
print(f"  Parallelism: {default_params.parallelism}")

# Use defaults
ph = PasswordHasher.from_parameters(default_params)

Parameter Validation

Validate parameters against current platform capabilities.

def validate_params_for_platform(params: Parameters) -> None:
    """
    Validate parameters against current platform limitations.
    
    Checks if the provided parameters are supported on the current
    platform and raises an exception if they are not.
    
    Args:
        params: Parameters to validate
    
    Raises:
        argon2.exceptions.UnsupportedParametersError: If parameters
            are not supported on current platform
    """

Usage Example

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

# Create parameters that might not work everywhere
params = Parameters(
    type=Type.ID,
    version=19,
    salt_len=16,
    hash_len=32,
    time_cost=3,
    memory_cost=65536,
    parallelism=8  # Might fail in WebAssembly
)

try:
    validate_params_for_platform(params)
    print("Parameters are supported on this platform")
except UnsupportedParametersError as e:
    print(f"Parameters not supported: {e}")
    # Fall back to platform defaults
    params = get_default_parameters()

Predefined Profiles

Standard parameter configurations following security recommendations.

RFC 9106 High Memory Profile

High security configuration for systems with abundant memory.

RFC_9106_HIGH_MEMORY: Parameters
"""
First recommended option per RFC 9106.

Configuration:
- Type: Argon2id  
- Memory: 2 GiB (2,097,152 KiB)
- Time cost: 1 iteration
- Parallelism: 4 threads
- Hash length: 32 bytes
- Salt length: 16 bytes

Use when: System has ample memory and security is paramount.
"""

Usage Example

from argon2.profiles import RFC_9106_HIGH_MEMORY
from argon2 import PasswordHasher

# Use high-security profile for sensitive applications
ph_secure = PasswordHasher.from_parameters(RFC_9106_HIGH_MEMORY)
admin_hash = ph_secure.hash("admin_password")

print(f"Using {RFC_9106_HIGH_MEMORY.memory_cost // 1024} MiB memory")
# Output: Using 2048 MiB memory

RFC 9106 Low Memory Profile

Balanced security configuration for memory-constrained environments.

RFC_9106_LOW_MEMORY: Parameters
"""
Second recommended option per RFC 9106.

Configuration:  
- Type: Argon2id
- Memory: 64 MiB (65,536 KiB)
- Time cost: 3 iterations
- Parallelism: 4 threads  
- Hash length: 32 bytes
- Salt length: 16 bytes

Use when: Memory is limited but good security is still needed.
This is the default profile used by argon2-cffi.
"""

Usage Example

from argon2.profiles import RFC_9106_LOW_MEMORY
from argon2 import PasswordHasher

# Balanced security/performance (default for new PasswordHasher())
ph_balanced = PasswordHasher.from_parameters(RFC_9106_LOW_MEMORY)
user_hash = ph_balanced.hash("user_password")

# This is equivalent to:
ph_default = PasswordHasher()  # Uses RFC_9106_LOW_MEMORY internally

Legacy Compatibility Profile

Historical parameter configuration for compatibility with older versions.

PRE_21_2: Parameters
"""
Pre-21.2.0 defaults for legacy compatibility.

Configuration:
- Type: Argon2id
- Memory: 100 MiB (102,400 KiB)  
- Time cost: 2 iterations
- Parallelism: 8 threads
- Hash length: 16 bytes
- Salt length: 16 bytes

Use when: Need compatibility with argon2-cffi versions 18.2.0-21.1.0.
"""

Usage Example

from argon2.profiles import PRE_21_2
from argon2 import PasswordHasher

# For systems upgrading from older argon2-cffi versions
ph_legacy = PasswordHasher.from_parameters(PRE_21_2)

# Check if existing hashes need upgrade
old_hash = "$argon2id$v=19$m=102400,t=2,p=8$..."
if ph_legacy.check_needs_rehash(old_hash):
    print("Hash uses legacy parameters")

Testing Profile

Minimal parameters for testing and development only.

CHEAPEST: Parameters
"""
Minimal parameters for testing purposes only.

Configuration:
- Type: Argon2id
- Memory: 8 KiB (very low)
- Time cost: 1 iteration  
- Parallelism: 1 thread
- Hash length: 4 bytes
- Salt length: 8 bytes

WARNING: Only use for testing! Provides minimal security.
"""

Usage Example

from argon2.profiles import CHEAPEST
from argon2 import PasswordHasher

# Only for unit tests and development
if __name__ == "__main__":
    ph_test = PasswordHasher.from_parameters(CHEAPEST)
    test_hash = ph_test.hash("test_password")
    print("Fast hash for testing:", test_hash)

Profile Selection Guide

High Security Applications

For applications requiring maximum security (financial, healthcare, government):

from argon2.profiles import RFC_9106_HIGH_MEMORY
from argon2 import PasswordHasher

# Maximum security - requires 2GB RAM per hash
ph = PasswordHasher.from_parameters(RFC_9106_HIGH_MEMORY)

General Web Applications

For typical web applications balancing security and performance:

from argon2 import PasswordHasher

# Uses RFC_9106_LOW_MEMORY by default (64MB RAM per hash)
ph = PasswordHasher()

Resource-Constrained Environments

For embedded systems, mobile apps, or shared hosting:

from argon2 import PasswordHasher, Parameters, Type

# Custom low-resource configuration
low_resource = Parameters(
    type=Type.ID,
    version=19,
    salt_len=16,
    hash_len=32,
    time_cost=2,        # Reduced iterations
    memory_cost=32768,  # 32 MiB memory
    parallelism=1       # Single thread
)

ph = PasswordHasher.from_parameters(low_resource)

Platform-Specific Configurations

Automatically adapt to platform capabilities:

from argon2.profiles import get_default_parameters
from argon2 import PasswordHasher

# Automatically adjusts for WebAssembly, mobile, etc.
platform_params = get_default_parameters()
ph = PasswordHasher.from_parameters(platform_params)

print(f"Using {platform_params.parallelism} threads")
# WebAssembly: 1 thread, other platforms: 4 threads

Migration Between Profiles

Handle password rehashing when changing security parameters:

from argon2 import PasswordHasher, extract_parameters
from argon2.profiles import RFC_9106_HIGH_MEMORY, RFC_9106_LOW_MEMORY

def upgrade_password_security(stored_hash: str, password: str) -> str:
    """Upgrade password hash to higher security parameters."""
    
    # Check current parameters
    current_params = extract_parameters(stored_hash)
    print(f"Current memory: {current_params.memory_cost} KiB")
    
    # Create new hasher with higher security
    new_ph = PasswordHasher.from_parameters(RFC_9106_HIGH_MEMORY)
    
    # Verify password with any parameters (auto-detects type)
    old_ph = PasswordHasher()
    old_ph.verify(stored_hash, password)  # Raises exception if wrong
    
    # Generate new hash with higher security
    new_hash = new_ph.hash(password)
    print(f"Upgraded to {RFC_9106_HIGH_MEMORY.memory_cost} KiB memory")
    
    return new_hash

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