{"id":7364,"library":"libpass","title":"libpass: Comprehensive Password Hashing Framework","description":"libpass is an actively maintained fork of the original `passlib` library, providing a comprehensive password hashing framework that supports over 30 schemes. It is currently at version 1.9.3 and receives regular updates to address compatibility issues, security concerns, and support newer Python versions.","status":"active","version":"1.9.3","language":"en","source_language":"en","source_url":"https://github.com/notypecheck/passlib","tags":["security","password-hashing","cryptography","authentication","passlib-fork"],"install":[{"cmd":"pip install libpass","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Optional backend for bcrypt hashing schemes. Requires `pip install libpass[bcrypt]`.","package":"bcrypt","optional":true},{"reason":"Optional backend for Argon2 hashing schemes. Requires `pip install libpass[argon2]`.","package":"argon2-cffi","optional":true},{"reason":"Provides the `crypt` module functionality for Python 3.13+ where it was removed. Included by default in libpass >= 1.8.0.","package":"legacycrypt","optional":false}],"imports":[{"note":"Despite the package name being `libpass`, it is a drop-in replacement for `passlib` and uses the original `passlib` import paths. Importing from `libpass.context` is for the separate `libpass-next` project.","wrong":"from libpass.context import CryptContext","symbol":"CryptContext","correct":"from passlib.context import CryptContext"},{"note":"Individual hashers are imported directly from `passlib.hash`.","symbol":"pbkdf2_sha256","correct":"from passlib.hash import pbkdf2_sha256"}],"quickstart":{"code":"from passlib.context import CryptContext\n\n# Configure a context with desired hashing schemes\n# Common schemes include 'sha512_crypt', 'bcrypt', 'pbkdf2_sha256', 'argon2'\ncontext = CryptContext(\n    schemes=[\"sha512_crypt\", \"bcrypt\", \"pbkdf2_sha256\", \"argon2\"],\n    # For real applications, configure rounds/iterations for security and performance\n    sha512_crypt__rounds=656000,\n    bcrypt__rounds=12,\n    pbkdf2_sha256__rounds=150000\n)\n\npassword = \"supersecretpassword\"\n\n# Hash a password\nhashed_password = context.hash(password)\nprint(f\"Hashed password: {hashed_password}\")\n\n# Verify a password against a hash\nis_valid = context.verify(password, hashed_password)\nprint(f\"Password valid: {is_valid}\")\n\n# Example with a wrong password\nis_invalid = context.verify(\"wrongpassword\", hashed_password)\nprint(f\"Wrong password valid: {is_invalid}\")\n","lang":"python","description":"This quickstart demonstrates how to use `passlib.context.CryptContext` to hash and verify passwords using multiple schemes. It showcases how to configure the context and perform basic hashing and verification operations."},"warnings":[{"fix":"Upgrade `libpass` to version 1.9.3 or newer, which includes improved fixup for `bcrypt` >= 5.0.0. Alternatively, explicitly pin `bcrypt < 5.0.0` in your project's dependencies if upgrading `libpass` is not immediately possible. Ensure passwords are truncated before being passed to `bcrypt` if they exceed 72 bytes.","message":"The `bcrypt` library (a common optional dependency) introduced a breaking change in version 5.0.0. Passwords longer than 72 bytes now raise a `ValueError` instead of being silently truncated. This can cause applications to fail if not handled.","severity":"breaking","affected_versions":"libpass < 1.9.3 when used with bcrypt >= 5.0.0"},{"fix":"Upgrade `libpass` to version 1.8.0 or newer. This version adds Python 3.13 support by incorporating `legacycrypt` to provide the necessary functionality.","message":"Python 3.13 removed the built-in `crypt` module, which older versions of `passlib` (and thus `libpass`) sometimes relied upon as a fallback. Running older `libpass` versions on Python 3.13+ can lead to `ModuleNotFoundError` or similar issues for certain hashing schemes.","severity":"breaking","affected_versions":"libpass < 1.8.0 with Python 3.13+"},{"fix":"Ensure that only `libpass` is installed in your Python environment. Uninstall `passlib` before installing `libpass` if you are migrating from the original library.","message":"Installing both the original `passlib` package and `libpass` concurrently can lead to unexpected behavior and import conflicts, as `libpass` is designed as a direct drop-in replacement.","severity":"gotcha","affected_versions":"All versions when both packages are installed"},{"fix":"Always use `from passlib.<module> import <symbol>` for all imports related to this library.","message":"While the package is installed as `libpass`, all imports within your code should use `passlib` (e.g., `from passlib.context import CryptContext`). Attempting to import from `libpass` directly will result in an `ImportError` for this specific fork.","severity":"gotcha","affected_versions":"All versions of libpass"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure `libpass` is installed via `pip install libpass`. Verify your virtual environment is activated, or that the correct Python interpreter is being used.","cause":"The `libpass` package is not installed in the currently active Python environment, or the virtual environment is not correctly activated.","error":"ModuleNotFoundError: No module named 'passlib'"},{"fix":"Upgrade `libpass` to version 1.9.3 or newer, as it includes compatibility fixes for `bcrypt` 5.0.0+. Alternatively, ensure that any passwords passed to `bcrypt` are 72 bytes or shorter, or pin `bcrypt<5.0.0` in your `requirements.txt`.","cause":"You are using `bcrypt` version 5.0.0 or higher with a password exceeding 72 bytes. `bcrypt` 5.0.0 changed its behavior to raise an error for overly long passwords, instead of silently truncating them.","error":"ValueError: password cannot be longer than 72 bytes, truncate manually if necessary"},{"fix":"Change your import statement to `from passlib.context import CryptContext`.","cause":"You are attempting to import from `libpass.context` instead of `passlib.context`. `libpass` maintains the original `passlib` import paths for compatibility.","error":"ImportError: cannot import name 'CryptContext' from 'libpass.context'"}]}