Argon2-cffi: Secure Password Hashing for Python

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

What is argon2-cffi?

The argon2-cffi library is the official Python wrapper for the Argon2 password hashing algorithm, implemented via the CFFI (C Foreign Function Interface). Argon2 is a modern password hashing algorithm that won the Password Hashing Competition in 2015 and has since become the gold standard for secure password storage.

The main advantage of argon2-cffi is that it delivers high performance through its C implementation while providing a convenient Python interface. The library is actively maintained by the community and regularly updated to meet the latest security standards.

Installation and Setup

Standard Installation

pip install argon2-cffi

Installation with Extra Dependencies

pip install argon2-cffi[dev]  # for development
pip install argon2-cffi[tests]  # for testing

Verify Installation

import argon2
print(argon2.__version__)

Argon2 Algorithm Variants

Argon2i (Data-Independent)

Argon2i is optimized to protect against side-channel attacks. It accesses memory independently of the password content, making it resistant to timing attacks. Recommended for scenarios where protection against runtime analysis is critical.

Argon2d (Data-Dependent)

Argon2d provides maximum protection against GPU attacks and attacks using specialized hardware. It uses data-dependent memory access, making it difficult to parallelize attacks. However, it is less protected against side-channel attacks.

Argon2id (Hybrid)

Argon2id is a hybrid mode that combines the advantages of both variants. It is the default in argon2-cffi and is recommended for most applications. The first passes are performed as Argon2i, and the remaining ones as Argon2d.

Quick Start

Basic Usage

from argon2 import PasswordHasher

# Create a hasher instance
ph = PasswordHasher()

# Hash a password
password = "my_super_secret_password"
hash_result = ph.hash(password)
print(f"Hash: {hash_result}")

# Verify a password
try:
    ph.verify(hash_result, password)
    print("Password is correct!")
except Exception as e:
    print(f"Password is incorrect: {e}")

Working with Different Data Types

from argon2 import PasswordHasher

ph = PasswordHasher()

# Hash a string
string_hash = ph.hash("string_password")

# Hash bytes
bytes_password = b"bytes_password"
bytes_hash = ph.hash(bytes_password)

# Verification
ph.verify(string_hash, "string_password")
ph.verify(bytes_hash, bytes_password)

PasswordHasher Configuration

Constructor Parameters

from argon2 import PasswordHasher, Type

ph = PasswordHasher(
    time_cost=3,        # Number of iterations (default is 2)
    memory_cost=65536,  # Memory usage in KB (default is 51200)
    parallelism=2,      # Number of threads (default is 1)
    hash_len=32,        # Hash length in bytes (default is 32)
    salt_len=16,        # Salt length in bytes (default is 16)
    encoding="utf-8",   # Encoding (default is "utf-8")
    type=Type.ID        # Argon2 type (default is Type.ID)
)

Impact of Parameters on Security

time_cost increases execution time linearly. Each increment of 1 doubles the hashing time.

memory_cost determines the memory usage in kilobytes. Larger values make attacks using specialized hardware more difficult.

Recommendations