Passlib is a comprehensive password hashing framework for Python, supporting over 30 hashing schemes. The current stable version is 1.7.4, which is the last series to support Python 2.x. Future versions (Passlib 1.8+) will require Python 3.5 or newer. It provides cross-platform implementations and a robust framework for managing password hashes in applications.
Install & Compatibility
Where this runs
tested against v1.7.4 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.930 runs
installs and imports cleanly · install 0.0s · import 0.091s · 21.3MB
glibcpy 3.10–3.930 runs
installs and imports cleanly · install 1.7s · import 0.081s · 22MB
20MB installed
● package 20MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
CryptContext
✓ from passlib.context import CryptContext
Recommended for new applications to manage multiple schemes, deprecation, and upgrades.
pbkdf2_sha256
✓ from passlib.hash import pbkdf2_sha256
For directly importing a specific hash algorithm, e.g., 'pbkdf2_sha256', 'bcrypt', 'argon2'.
This quickstart demonstrates how to use `CryptContext` to hash and verify passwords. `CryptContext` provides a flexible way to manage various hashing schemes, including automatic deprecation and upgrade detection, which is crucial for long-term password security. Modern schemes like `pbkdf2_sha256`, `bcrypt`, and `argon2` are recommended.
from passlib.context import CryptContext
# For new applications, it's recommended to use CryptContext
# schemes=['bcrypt'] or schemes=['argon2'] are good modern choices.
# 'deprecated="auto"' ensures older hashes are automatically marked for upgrade.
pwd_context = CryptContext(
schemes=["pbkdf2_sha256", "bcrypt"],
deprecated="auto",
# Optionally, configure default rounds for schemes.
# Adjust these values based on current security recommendations and desired CPU cost.
pbkdf2_sha256__rounds=600000,
bcrypt__rounds=12,
)
password = "supersecretpassword"
# Hash the password
hashed_password = pwd_context.hash(password)
print(f"Hashed password: {hashed_password}")
# Verify the password
is_valid = pwd_context.verify(password, hashed_password)
print(f"Password valid: {is_valid}")
# Verify with wrong password
is_invalid = pwd_context.verify("wrongpassword", hashed_password)
print(f"Wrong password valid: {is_invalid}")
# Check if hash needs to be upgraded (e.g., if a deprecated scheme was used or rounds are too low)
needs_upgrade = pwd_context.needs_update(hashed_password)
print(f"Hash needs upgrade: {needs_upgrade}")
if needs_upgrade:
print("Upgrading hash...")
new_hashed_password = pwd_context.hash(password)
print(f"New Hashed password after upgrade: {new_hashed_password}")
Debug
Known issues
breakingPasslib 1.7.x is the last series to support Python 2.x, 3.3, and 3.4. Passlib 1.8 and later will require Python >= 3.5.fixEnsure your project uses Python 3.5+ before upgrading to Passlib 1.8. Consider migrating Python 2.x code if still in use.
affects: 1.8+
breakingThe `crypt` module will be removed in Python 3.13. While Passlib 1.7.4 includes fallbacks, there are concerns about its long-term maintenance and full compatibility with Python 3.13 without active updates to address this.fixMonitor Passlib's official channels for updates regarding Python 3.13 compatibility. Consider alternatives like `pwdlib` if issues arise or maintenance remains stalled.
affects: 1.7.4 (potential issues with Python 3.13)
gotchaPasslib has known compatibility issues with `bcrypt` versions 4.1.0 and above. When using the `bcrypt` scheme, Passlib may encounter an `AttributeError` due to changes in the `bcrypt` module.fixDowngrade the `bcrypt` package to version `4.0.1` or lower (`pip install bcrypt==4.0.1`) if you rely on Passlib's `bcrypt` scheme.
affects: 1.7.4 with bcrypt >= 4.1.0
gotchaDirect string comparison (e.g., `hashed_password == other_hash`) to verify passwords is insecure and vulnerable to timing attacks.fixAlways use the `.verify()` method provided by `Passlib` (e.g., `pwd_context.verify(password, hashed_hash)`) which uses constant-time comparison.
affects: All
gotchaCalling `PasswordHash.hash()` or `CryptContext.hash()` multiple times with the same plaintext password will produce different hash strings each time (for salted schemes). This is expected behavior as a new random salt is generated with each call.fixUnderstand that different hash outputs for the same password are a security feature, not a bug. Store only one hash per password and use `.verify()` for checks.
affects: All
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'passlib'
The 'passlib' library is not installed in the Python environment being used, or the Python interpreter cannot find it due to environment path issues or virtual environment misconfiguration.
fixEnsure 'passlib' is installed in your active Python environment using pip: `pip install passlib` or `pip3 install passlib`. If using a virtual environment, activate it before installing.
TypeError: Unicode-objects must be encoded before hashing
This error occurs when attempting to hash a Python Unicode string directly with 'passlib' (or its underlying hashing backends like bcrypt) without first encoding it into bytes.
fixEncode the password string to bytes (e.g., UTF-8) before passing it to the hashing function: `password.encode('utf-8')`. ValueError: password cannot be longer than 72 bytes
The bcrypt hashing algorithm, often used via 'passlib', has a hard limit of 72 bytes for passwords. This error indicates the provided password exceeds this length. This can also be caused by compatibility issues with newer `bcrypt` versions (e.g., 5.0.0) where internal behavior changes caused problems even with shorter inputs.
fixEither ensure passwords do not exceed 72 bytes (e.g., `password[:72]`) or, if the issue is a `bcrypt` version conflict, pin `bcrypt` to an earlier compatible version like 4.3.0 in your `requirements.txt`: `bcrypt==4.3.0`.
AttributeError: module 'bcrypt' has no attribute 'about'
This error typically arises from an incompatibility between the installed 'passlib' version and a newer version of the 'bcrypt' backend library, where 'bcrypt' removed the `__about__` attribute that 'passlib' was attempting to access.
fixDowngrade the 'bcrypt' library to a version compatible with 'passlib' 1.7.4, for example: `pip install "bcrypt==4.0.1"` or `pip install "bcrypt<4.1.0"`.
ValueError: Not a valid password hash
This error occurs when `passlib` tries to parse or verify a string that does not conform to a valid hash format for the expected scheme.
fixEnsure the hash string passed to methods like `hash.verify()` or `hash.identify()` is a valid, correctly formatted hash previously generated by `passlib` or a compatible system.
Audit
Dependencies
python-bcryptoptionalOptional: accelerates Bcrypt hashes. Users may need to pin version < 4.1.0 due to compatibility issues with passlib's internal handling.
python-fastpbkdf2optionalOptional: accelerates PBKDF2-based hashes.
python-scryptoptionalOptional: accelerates SCrypt hashes.