{"id":7340,"library":"keyrings-cryptfile","title":"Keyrings Cryptfile","description":"keyrings.cryptfile is a Python library that provides an encrypted file keyring backend for the standard `keyring` package. It enables secure storage of plaintext passwords in a portable encrypted file, particularly useful when typical desktop environment keyring implementations are unsuitable. The project encrypts data using Argon2 for key derivation and authenticated AES encryption (GCM by default). The latest version is 1.3.9, released on November 20, 2022. While there isn't a strict release cadence, updates appear to be infrequent.","status":"active","version":"1.3.9","language":"en","source_language":"en","source_url":"https://github.com/frispete/keyrings.cryptfile","tags":["security","keyring","encryption","password-management"],"install":[{"cmd":"pip install keyrings-cryptfile","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Provides the base keyring interface that keyrings.cryptfile extends as a backend.","package":"keyring"},{"reason":"Required for the cryptographic operations (AES encryption, PBKDF2).","package":"pycryptodome"}],"imports":[{"note":"The package name is `keyrings-cryptfile` but the top-level import is `keyrings.cryptfile` due to namespace packaging, specifically `keyrings.cryptfile.cryptfile` for the main class.","wrong":"from keyrings_cryptfile.cryptfile import CryptFileKeyring","symbol":"CryptFileKeyring","correct":"from keyrings.cryptfile.cryptfile import CryptFileKeyring"}],"quickstart":{"code":"import keyring\nfrom keyrings.cryptfile.cryptfile import CryptFileKeyring\nimport os\n\n# Create an instance of the CryptFileKeyring\nkr = CryptFileKeyring()\n\n# Optional: Set a keyring key programmatically (e.g., from an environment variable)\n# If not set, the library will prompt interactively for the master password.\n# Hardcoding the keyring_key is insecure and should be avoided in production.\nkeyring_master_password = os.environ.get('KEYRING_CRYPTFILE_MASTER_PASSWORD', '')\nif keyring_master_password:\n    kr.keyring_key = keyring_master_password # type: ignore\n\n# Set a password for a service and user\nservice_name = \"my_application\"\nusername = \"api_user\"\nsecret_password = \"my_super_secret_password\"\n\n# This will prompt for the master password if not set programmatically\nkr.set_password(service_name, username, secret_password)\nprint(f\"Password for service '{service_name}' and user '{username}' set successfully.\")\n\n# Retrieve the password\n# This will also prompt for the master password if not set programmatically\nretrieved_password = kr.get_password(service_name, username)\n\nif retrieved_password:\n    print(f\"Retrieved password for '{service_name}' user '{username}': {retrieved_password}\")\nelse:\n    print(f\"No password found for '{service_name}' user '{username}'.\")\n\n# To make CryptFileKeyring the default for the standard `keyring` library:\n# keyring.set_keyring(kr)\n# # Now, calls to keyring.set_password() or keyring.get_password() will use CryptFileKeyring\n# keyring.set_password(\"another_service\", \"another_user\", \"another_secret\")\n# print(keyring.get_password(\"another_service\", \"another_user\"))","lang":"python","description":"This quickstart demonstrates how to initialize the `CryptFileKeyring`, set a master password (either interactively or via an environment variable for non-interactive use), store a service password, and then retrieve it. It also shows how to optionally integrate it with the main `keyring` library."},"warnings":[{"fix":"Always provide the `keyring_key` securely, for example, by prompting the user via `getpass`, or by retrieving it from an environment variable in non-interactive environments (e.g., `os.environ.get('KEYRING_CRYPTFILE_MASTER_PASSWORD')`).","message":"Hardcoding the `keyring_key` (the master password for the encrypted file) directly in code is a severe security vulnerability, as it defeats the purpose of encryption.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For automated scripts, ensure `kr.keyring_key` is set before calling password operations to avoid interactive prompts. Be aware of the inherent cryptographic delay in performance-sensitive contexts.","message":"Operations like `set_password()` and `get_password()` can involve an interactive prompt for the keyring's master password if `keyring_key` is not set programmatically. The Key Derivation Function (KDF) also introduces a noticeable delay (~1 second) for cryptographic processing.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure `keyring` is installed (`pip install keyring`) and `keyrings-cryptfile` is installed. If automatic selection is not working, explicitly set the keyring using `keyring.set_keyring(kr)` where `kr` is an instance of `CryptFileKeyring`.","message":"As a backend, `keyrings.cryptfile` relies on the `keyring` library for integration. If `keyring` is not installed or configured to use this backend, it might not be automatically selected.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Check the GitHub issues for `keyrings-cryptfile` for known compatibility problems. Consider pinning the `keyring` library to an older, compatible version (e.g., `pip install keyring==X.Y.Z`) or awaiting an update to `keyrings-cryptfile`.","cause":"This error likely indicates a compatibility issue between `keyrings-cryptfile` and a newer version of the `keyring` library, where `properties` might have been moved or removed from `keyring.util`.","error":"ImportError: cannot import name 'properties' from 'keyring.util'"},{"fix":"Verify that the `keyring_key` (master password) provided is absolutely correct. If the password is correct and the error persists, the keyring file may be damaged, and recreating it might be the only solution.","cause":"This error typically occurs during decryption, indicating that the master password (`keyring_key`) used is incorrect, the encrypted file has been corrupted, or it has been tampered with.","error":"ValueError: MAC check failed"},{"fix":"Before any password operations, ensure that the `kr.keyring_key` attribute is set programmatically, typically by reading the master password from a secure environment variable (e.g., `os.environ.get('KEYRING_CRYPTFILE_MASTER_PASSWORD')`).","cause":"The `keyrings.cryptfile` backend uses `getpass.getpass()` for its master password if `kr.keyring_key` is not set. In a non-interactive environment, this will cause the application to hang indefinitely while waiting for input.","error":"Application hangs or waits for input in a non-interactive environment (e.g., CI/CD pipeline)"}]}