argon2-cffi

repository·main·Indexed 20 days ago

https://github.com/hynek/argon2-cffi

A Python library providing a secure implementation of the Argon2 password hashing algorithm. It features a high-level PasswordHasher API for hashing and verifying passwords, support for RFC 9106 profiles, and a low-level API for specialized cryptographic needs (Argon2d, Argon2i, and Argon2id). The package includes a CLI for benchmarking performance and supports vendored or system-wide Argon2 installations.

Tokens
8.6K
Snippets
28
Records
46
Agent score
69%

What's inside argon2-cffi

  1. What is Argon2 and its variants?

    main

    Argon2 is a secure password hashing algorithm standardized in RFC 9106. It is designed to be both time-configurable (runtime) and memory-configurable (memory consumption), making it resistant to GPU and ASIC-based parallel cracking attacks.

    There are three main variants:

    • Argon2d: Optimized for resistance against time–memory trade-offs.
    • Argon2i: Optimized for resistance against side-channel attacks.
    • Argon2id: A hybrid variant that combines the strengths of both d and i. It is considered the main variant and the recommended choice for most applications.
  2. Configure Argon2 using Profiles

    main

    Argon2 profiles provide pre-defined sets of parameters (time cost, memory cost, parallelism, etc.) optimized for different environments. You can use these to balance security and performance.

    Available Profiles:

    • RFC_9106_HIGH_MEMORY: The "FIRST RECOMMENDED option". Requires ~2 GiB of RAM. Use for high-security needs where memory is available.
    • RFC_9106_LOW_MEMORY: The "SECOND RECOMMENDED option". Uses ~64 MiB of RAM. This is the default for PasswordHasher.
    • PRE_21_2: Legacy profile used in versions 18.2.0 through 21.2.0. Uses ~100 MiB of RAM.
    • CHEAPEST: Warning: Only for testing! Do not use in production.

    You can test profile performance in your environment via the CLI:

    python -m argon2 --profile RFC_9106_HIGH_MEMORY
  3. Migrating from bcrypt, PBKDF2, scrypt, or yescrypt

    main
    If you are currently using bcrypt, PBKDF2, scrypt, or yescrypt, there is no immediate danger or requirement to migrate. However, if you are implementing a new password hashing system today, Argon2 is recommended as a superior, future-proof choice. Users of scrypt or yescrypt are considered well-protected for the foreseeable future.
  4. GIL release behavior in argon2-cffi

    main
    Yes, argon2-cffi releases the Global Interpreter Lock (GIL), allowing for better performance in multi-threaded Python applications during the computationally intensive hashing process.
  5. Getting started with argon2-cffi

    main
    To begin using argon2-cffi, start by learning the core argon2 module. This module provides the primary interface for password hashing and verification. For more advanced usage, refer to the API documentation, parameter guides, and CLI instructions.
  6. Use RFC 9106 recommended profiles

    main

    For standard security recommendations, you can use the pre-defined profiles from the argon2.profiles module. These profiles follow the RFC 9106 standard and can be loaded into a PasswordHasher instance using the from_parameters() method.

    Available profiles:

    • argon2.profiles.RFC_9106_HIGH_MEMORY (First recommendation)
    • argon2.profiles.RFC_9106_LOW_MEMORY (Second recommendation)

    You can test these profiles using the argon2-cffi CLI with the --profile argument to ensure they meet your performance requirements.

    import argon2
    
    # Load the high memory RFC 9106 profile
    ph = argon2.PasswordHasher.from_parameters(argon2.profiles.RFC_9106_HIGH_MEMORY)
  7. How to hash and verify passwords with PasswordHasher

    main

    The recommended way to use argon2-cffi is via the high-level PasswordHasher class. It uses officially recommended Argon2 parameters (defaulting to 64 MB of memory) designed to provide a verification time of 40--50ms on modern hardware.

    To hash a password, use ph.hash(password). To verify a password against a hash, use ph.verify(hash, password). If the password is incorrect, ph.verify raises an argon2.exceptions.VerifyMismatchError.

    from argon2 import PasswordHasher
    
    ph = PasswordHasher()
    
    # Hashing a password
    hash = ph.hash("correct horse battery staple")
    
    # Verifying a password
    try:
        ph.verify(hash, "correct horse battery staple")
        print("Password matches!")
    except argon2.exceptions.VerifyMismatchError:
        print("Password does not match!")
    
    # Checking if the hash needs to be updated (e.g., due to parameter changes)
    needs_rehash = ph.check_needs_rehash(hash)
  8. Securely hash passwords with argon2.PasswordHasher

    main

    For most use cases, you should use the argon2.PasswordHasher class with its default parameters. This provides a secure implementation of the Argon2 algorithm without requiring manual tuning of complexity parameters.

    import argon2
    
    ph = argon2.PasswordHasher()
    
    # Hashing a password
    hash = ph.hash("my_secret_password")
    
    # Verifying a password
    try:
        ph.verify(hash, "my_secret_password")
    except argon2.exceptions.VerifyMismatchError:
        # Handle incorrect password
        pass
  9. Hash and verify passwords with PasswordHasher

    main

    The PasswordHasher class provides a high-level API for securely hashing and verifying passwords using the Argon2 algorithm.

    Key workflows:

    1. Hashing: Use ph.hash(password) to generate a secure hash string.
    2. Verification: Use ph.verify(hash, password) to check if a password matches a hash. This returns True if successful, or raises argon2.exceptions.VerifyMismatchError if the password is incorrect.
    3. Rehash Check: Use ph.check_needs_rehash(hash) to determine if a stored hash should be updated (e.g., if the security parameters have changed).
    from argon2 import PasswordHasher
    
    ph = PasswordHasher()
    
    # Hashing a password
    hash = ph.hash("correct horse battery staple")
    
    # Verifying a password
    ph.verify(hash, "correct horse battery staple")  # Returns True
    
    # Checking if the hash needs to be updated
    ph.check_needs_rehash(hash)  # Returns False
    
    # Handling incorrect passwords
    try:
        ph.verify(hash, "wrong password")
    except argon2.exceptions.VerifyMismatchError:
        # Handle mismatch
        pass
  10. Install argon2-cffi using the vendored Argon2

    main

    The simplest and safest way to install argon2-cffi is to use the default installation method. This uses a vendored version of Argon2's C code provided by argon2-cffi-bindings, which has been specifically tested for compatibility. Binary wheels for macOS, Windows, and Linux are provided on PyPI and should be used automatically by modern versions of pip.

    $ python -m pip install argon2-cffi
  11. Fine-tune Argon2 parameters manually

    main

    If the default argon2.PasswordHasher or the RFC profiles do not suit your hardware or performance needs, you can manually tune the following parameters:

    1. type: Choose the Argon2 variant. If unsure, use argon2.low_level.Type.ID (Argon2id).
    2. parallelism: The number of threads to use per call (referred to as "lanes" in RFC 9106). 4 threads is recommended.
    3. memory_cost: The amount of memory used per call, measured in Kibibytes (KiB, 1024 bytes).
    4. salt_len: The length of the salt. 16 bytes is standard; 8 bytes is a minimum for space-constrained environments.
    5. hash_len: The length of the resulting hash (tag length). 16 bytes is sufficient for verification.
    6. time_cost: The number of iterations.

    Tuning Strategy:

    • Start with time_cost=1 and measure the execution time on your hardware.
    • Increase time_cost until the hashing time reaches your desired threshold (balancing security vs. user experience).
    • If time_cost=1 is already too slow, decrease memory_cost instead.