{"id":252,"library":"cryptography","title":"cryptography","description":"The cryptography library (pyca/cryptography) provides cryptographic recipes and primitives to Python developers, aiming to be a 'cryptographic standard library'. It offers both high-level recipes (e.g., Fernet symmetric encryption) and low-level hazmat (hazardous materials) primitives covering symmetric ciphers, asymmetric algorithms (RSA, EC, DSA), message digests, KDFs, X.509, and more. Current stable version is 46.0.6 (released 2026-03-25). The project releases frequently—typically multiple times per major version cycle—with major versions arriving several times per year.","status":"active","version":"46.0.6","language":"python","source_language":"en","source_url":"https://github.com/pyca/cryptography","tags":["cryptography","encryption","rsa","aes","fernet","x509","tls","hashing","kdf","security","openssl","rust"],"install":[{"cmd":"pip install cryptography","lang":"bash","label":"Install (standard)"},{"cmd":"pip install --upgrade pip && pip install cryptography","lang":"bash","label":"Install with updated pip (avoids source builds)"}],"dependencies":[{"reason":"C FFI bindings layer; pulled in automatically on CPython when installing from source","package":"cffi","optional":false},{"reason":"System OpenSSL required only when building from source; pre-built wheels bundle OpenSSL statically","package":"openssl","optional":true},{"reason":"Required to compile from source (not from wheel); pre-built wheels ship Rust-compiled extensions","package":"rust / cargo","optional":true}],"imports":[{"note":"High-level authenticated symmetric encryption; preferred over raw hazmat APIs for most use cases","symbol":"Fernet","correct":"from cryptography.fernet import Fernet"},{"note":"The `backend` parameter was removed in 3.x; passing `default_backend()` to Cipher() raises TypeError on modern versions","wrong":"from cryptography.hazmat.backends import default_backend; Cipher(..., backend=default_backend())","symbol":"Cipher, algorithms, modes","correct":"from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes"},{"note":"Simpler authenticated encryption API; handles IV/tag automatically compared to the Cipher+GCM mode pattern","symbol":"AESGCM (AEAD shortcut)","correct":"from cryptography.hazmat.primitives.ciphers.aead import AESGCM"},{"note":"The `backend` keyword argument was removed; call without it: rsa.generate_private_key(public_exponent=65537, key_size=2048)","wrong":"rsa.generate_private_key(65537, 2048, backend=default_backend())","symbol":"rsa.generate_private_key","correct":"from cryptography.hazmat.primitives.asymmetric import rsa"},{"note":"Use padding.OAEP for RSA encryption and padding.PSS for RSA signatures; PKCS1v15 is legacy only","symbol":"padding (asymmetric)","correct":"from cryptography.hazmat.primitives.asymmetric import padding"},{"note":"Used with asymmetric sign/verify and HMAC; e.g. hashes.SHA256()","symbol":"hashes","correct":"from cryptography.hazmat.primitives import hashes"},{"note":"For loading/serializing PEM/DER keys; use serialization.load_pem_private_key(), not legacy OpenSSL backend helpers","symbol":"serialization","correct":"from cryptography.hazmat.primitives import serialization"},{"note":"X.509 certificate parsing and building; use x509.load_pem_x509_certificate()","symbol":"x509","correct":"from cryptography import x509"}],"quickstart":{"code":"# --- High-level: Fernet (recommended for most use cases) ---\nfrom cryptography.fernet import Fernet\n\nkey = Fernet.generate_key()          # Must be stored securely; bytes\nf = Fernet(key)\ntoken = f.encrypt(b\"secret message\")  # Returns URL-safe base64 token\nplaintext = f.decrypt(token)          # Raises InvalidToken if tampered\nassert plaintext == b\"secret message\"\n\n# --- Low-level: AES-GCM via hazmat (authenticated encryption) ---\nimport os\nfrom cryptography.hazmat.primitives.ciphers.aead import AESGCM\n\naes_key = AESGCM.generate_key(bit_length=256)  # 32 random bytes\naesgcm = AESGCM(aes_key)\nnonce = os.urandom(12)               # 96-bit nonce; NEVER reuse with same key\nciphertext = aesgcm.encrypt(nonce, b\"secret data\", b\"optional AAD\")\ndecrypted = aesgcm.decrypt(nonce, ciphertext, b\"optional AAD\")\nassert decrypted == b\"secret data\"\n\n# --- RSA key generation & sign/verify ---\nfrom cryptography.hazmat.primitives.asymmetric import rsa, padding\nfrom cryptography.hazmat.primitives import hashes\n\nprivate_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)\npublic_key = private_key.public_key()\nmessage = b\"message to sign\"\nsignature = private_key.sign(\n    message,\n    padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH),\n    hashes.SHA256()\n)\npublic_key.verify(\n    signature, message,\n    padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH),\n    hashes.SHA256()\n)  # Raises InvalidSignature if verification fails\nprint(\"All operations succeeded\")\n","lang":"python","description":"Fernet high-level symmetric encryption (recommended starting point) plus AES-GCM via hazmat for authenticated low-level encryption."},"warnings":[{"fix":"Remove all `backend=` keyword arguments. Modern API: `rsa.generate_private_key(public_exponent=65537, key_size=2048)` with no backend argument.","message":"The `backend` parameter was removed from all hazmat constructors (Cipher, rsa.generate_private_key, ec.generate_private_key, etc.). Passing `backend=default_backend()` now raises TypeError.","severity":"breaking","affected_versions":"<3.x to >=3.x migration"},{"fix":"Replace `key.signer(...)` with `key.sign(...)` and `key.verifier(...)` with `key.verify(...)` directly.","message":"`signer()` and `verifier()` methods on public/private key objects were removed in 44.0.0 after being deprecated since 2.0.","severity":"breaking","affected_versions":"<44.0.0 code running on >=44.0.0"},{"fix":"Upgrade system OpenSSL to 3.0+, or use pre-built wheels (which bundle a recent OpenSSL statically).","message":"OpenSSL 1.1.x support was removed; OpenSSL 3.0.0 or later is now required when building from source. LibreSSL < 4.1 also dropped.","severity":"breaking","affected_versions":">=47.0.0 (upcoming dev), applies to source builds"},{"fix":"Catch `cryptography.exceptions.UnsupportedAlgorithm` instead of (or in addition to) `ValueError` when loading keys.","message":"Loading keys with unsupported algorithms or explicit curve encodings now raises `UnsupportedAlgorithm` instead of `ValueError`.","severity":"breaking","affected_versions":">=46.0.0"},{"fix":"Migrate to AES-GCM or ChaCha20-Poly1305 (AEAD modes) for new code. Import from `cryptography.hazmat.decrepit` if you must keep using them temporarily.","message":"CFB, OFB, and CFB8 modes have been moved to 'Decrepit cryptography' and deprecated in `cryptography.hazmat.primitives.ciphers.modes`. They will be removed in 49.0.0. Camellia cipher is similarly deprecated.","severity":"deprecated","affected_versions":">=46.0.0, removed in 49.0.0"},{"fix":"Always prefer authenticated encryption: use `AESGCM`, `ChaCha20Poly1305`, or `Cipher` with `modes.GCM`. Never use ECB in production.","message":"ECB mode (`modes.ECB`) is available but insecure—it encrypts identical plaintext blocks to identical ciphertext blocks, leaking data patterns. The library does not prevent its use.","severity":"gotcha","affected_versions":"all"},{"fix":"Install via `pip install cryptography` with an up-to-date pip to receive a pre-built binary wheel. If building from source, install Rust via rustup and ensure version >= 1.83.0.","message":"When building from source (not from a wheel), a Rust toolchain (cargo) is required. On Alpine Linux < 3.21 and older Debian/Ubuntu, the default Rust is too old.","severity":"gotcha","affected_versions":"all source builds"}],"env_vars":null,"last_verified":"2026-05-12T12:22:17.213Z","next_check":"2026-06-25T00:00:00.000Z","problems":[{"fix":"Ensure the library is installed for your active Python environment. If using a virtual environment, activate it first. For most users, run: `pip install cryptography` or `python -m pip install cryptography`.","cause":"The 'cryptography' package is not installed in the Python environment being used, or the Python interpreter cannot find the installed library.","error":"ModuleNotFoundError: No module named 'cryptography'"},{"fix":"First, upgrade `pip` and `setuptools`: `python -m pip install --upgrade pip setuptools`. If the error persists: \n- On Linux, install development headers (e.g., `sudo apt-get install build-essential libssl-dev libffi-dev` on Debian/Ubuntu, or `sudo yum install redhat-rpm-config gcc libffi-devel python3-devel openssl-devel` on RHEL/CentOS).\n- On macOS, install Xcode Command Line Tools (`xcode-select --install`) and OpenSSL (e.g., `brew install openssl`).\n- On Windows, install Microsoft Visual C++ Build Tools.\n- If specifically 'Can not find Rust compiler' appears, install Rust: `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`.","cause":"Installation of `cryptography` failed because it needs to be built from source, and the necessary build tools (like a C compiler, OpenSSL development headers, or the Rust compiler) are missing on the system, or `pip` is outdated and cannot find pre-compiled wheels.","error":"ERROR: Could not build wheels for cryptography which use PEP 517 and cannot be installed directly OR Can not find Rust compiler."},{"fix":"For large data, use hybrid encryption: encrypt the data with a symmetric cipher (e.g., AES/Fernet), and then encrypt only the much smaller symmetric key with RSA.","cause":"This error often occurs with asymmetric encryption (e.g., RSA) when attempting to encrypt data larger than the maximum plaintext size allowed by the key and padding scheme. RSA encryption has strict limits on the size of data it can encrypt directly.","error":"ValueError: Encryption/decryption failed."},{"fix":"Convert the string data to bytes using the `.encode()` method with an appropriate encoding (e.g., UTF-8). For example, `b'your_string'` or `'your_string'.encode('utf-8')`.","cause":"A cryptographic function that expects a `bytes`-like object (e.g., for plaintext, ciphertext, or keys) received a Python string (`str`) instead.","error":"TypeError: data must be bytes"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.4,"disk_size":"31.8M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.4,"disk_size":"33.2M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.4,"disk_size":"32M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.4,"disk_size":"34M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.5,"disk_size":"33.4M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.5,"disk_size":"35.3M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.5,"disk_size":"34M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.5,"disk_size":"36M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.2,"disk_size":"27.9M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.2,"disk_size":"27.1M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.2,"disk_size":"28M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.2,"disk_size":"27M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.4,"disk_size":"27.9M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.4,"disk_size":"26.7M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.2,"disk_size":"28M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.2,"disk_size":"27M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.3,"disk_size":"32.1M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.3,"disk_size":"33.5M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.3,"disk_size":"32M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.3,"disk_size":"34M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}