cryptography

raw JSON →
46.0.6 verified Tue May 12 auth: no python install: verified quickstart: verified

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.

pip install cryptography
error ModuleNotFoundError: No module named 'cryptography'
cause The 'cryptography' package is not installed in the Python environment being used, or the Python interpreter cannot find the installed library.
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.
error ERROR: Could not build wheels for cryptography which use PEP 517 and cannot be installed directly OR Can not find Rust compiler.
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.
fix
First, upgrade pip and setuptools: python -m pip install --upgrade pip setuptools. If the error persists: - 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). - On macOS, install Xcode Command Line Tools (xcode-select --install) and OpenSSL (e.g., brew install openssl). - On Windows, install Microsoft Visual C++ Build Tools. - If specifically 'Can not find Rust compiler' appears, install Rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh.
error ValueError: Encryption/decryption failed.
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.
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.
error TypeError: data must be bytes
cause A cryptographic function that expects a `bytes`-like object (e.g., for plaintext, ciphertext, or keys) received a Python string (`str`) instead.
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').
breaking 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.
fix Remove all `backend=` keyword arguments. Modern API: `rsa.generate_private_key(public_exponent=65537, key_size=2048)` with no backend argument.
breaking `signer()` and `verifier()` methods on public/private key objects were removed in 44.0.0 after being deprecated since 2.0.
fix Replace `key.signer(...)` with `key.sign(...)` and `key.verifier(...)` with `key.verify(...)` directly.
breaking 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.
fix Upgrade system OpenSSL to 3.0+, or use pre-built wheels (which bundle a recent OpenSSL statically).
breaking Loading keys with unsupported algorithms or explicit curve encodings now raises `UnsupportedAlgorithm` instead of `ValueError`.
fix Catch `cryptography.exceptions.UnsupportedAlgorithm` instead of (or in addition to) `ValueError` when loading keys.
deprecated 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.
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.
gotcha 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.
fix Always prefer authenticated encryption: use `AESGCM`, `ChaCha20Poly1305`, or `Cipher` with `modes.GCM`. Never use ECB in production.
gotcha 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.
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.
pip install --upgrade pip && pip install cryptography
python os / libc variant status wheel install import disk
3.10 alpine (musl) --upgrade - - 0.02s 31.8M
3.10 alpine (musl) cryptography - - 0.02s 33.2M
3.10 slim (glibc) --upgrade - - 0.02s 32M
3.10 slim (glibc) cryptography - - 0.02s 34M
3.11 alpine (musl) --upgrade - - 0.04s 33.4M
3.11 alpine (musl) cryptography - - 0.04s 35.3M
3.11 slim (glibc) --upgrade - - 0.03s 34M
3.11 slim (glibc) cryptography - - 0.03s 36M
3.12 alpine (musl) --upgrade - - 0.03s 27.9M
3.12 alpine (musl) cryptography - - 0.03s 27.1M
3.12 slim (glibc) --upgrade - - 0.03s 28M
3.12 slim (glibc) cryptography - - 0.03s 27M
3.13 alpine (musl) --upgrade - - 0.03s 27.9M
3.13 alpine (musl) cryptography - - 0.03s 26.7M
3.13 slim (glibc) --upgrade - - 0.03s 28M
3.13 slim (glibc) cryptography - - 0.03s 27M
3.9 alpine (musl) --upgrade - - 0.02s 32.1M
3.9 alpine (musl) cryptography - - 0.02s 33.5M
3.9 slim (glibc) --upgrade - - 0.02s 32M
3.9 slim (glibc) cryptography - - 0.02s 34M

Fernet high-level symmetric encryption (recommended starting point) plus AES-GCM via hazmat for authenticated low-level encryption.

# --- High-level: Fernet (recommended for most use cases) ---
from cryptography.fernet import Fernet

key = Fernet.generate_key()          # Must be stored securely; bytes
f = Fernet(key)
token = f.encrypt(b"secret message")  # Returns URL-safe base64 token
plaintext = f.decrypt(token)          # Raises InvalidToken if tampered
assert plaintext == b"secret message"

# --- Low-level: AES-GCM via hazmat (authenticated encryption) ---
import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

aes_key = AESGCM.generate_key(bit_length=256)  # 32 random bytes
aesgcm = AESGCM(aes_key)
nonce = os.urandom(12)               # 96-bit nonce; NEVER reuse with same key
ciphertext = aesgcm.encrypt(nonce, b"secret data", b"optional AAD")
decrypted = aesgcm.decrypt(nonce, ciphertext, b"optional AAD")
assert decrypted == b"secret data"

# --- RSA key generation & sign/verify ---
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes

private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
message = b"message to sign"
signature = private_key.sign(
    message,
    padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH),
    hashes.SHA256()
)
public_key.verify(
    signature, message,
    padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH),
    hashes.SHA256()
)  # Raises InvalidSignature if verification fails
print("All operations succeeded")