{"id":562,"library":"pycryptodome","title":"PyCryptodome","description":"PyCryptodome is a self-contained Python package providing low-level cryptographic primitives. It offers a comprehensive suite of algorithms for encryption, decryption, hashing, and digital signatures, acting as a maintained fork and drop-in replacement for the outdated PyCrypto library. It supports Python 2.7, Python 3.7+, and PyPy, with a consistent release cadence.","status":"active","version":"3.23.0","language":"python","source_language":"en","source_url":"https://github.com/Legrandin/pycryptodome/","tags":["cryptography","security","encryption","hashing","signature","aes","rsa","gcm"],"install":[{"cmd":"pip install pycryptodome","lang":"bash","label":"Install PyCryptodome"}],"dependencies":[{"reason":"Optional for faster public key operations on Unix-like systems, if compiled from source.","package":"gmp","optional":true},{"reason":"Required for compiling C extensions from source on Windows if wheels are not available or custom compilation is desired.","package":"Visual Studio Build Tools","optional":true}],"imports":[{"note":"The `pycryptodome` package installs its modules under the `Crypto` namespace for backward compatibility with the old `PyCrypto` library. Avoid `Cryptodome` unless `pycryptodomex` is explicitly installed.","wrong":"from Cryptodome.Cipher import AES","symbol":"AES","correct":"from Crypto.Cipher import AES"},{"note":"Standard import path for cryptographic random number generation.","symbol":"get_random_bytes","correct":"from Crypto.Random import get_random_bytes"},{"note":"Standard import path for Password-Based Key Derivation Function 2.","symbol":"PBKDF2","correct":"from Crypto.Protocol.KDF import PBKDF2"},{"note":"Standard import path for RSA public key operations.","symbol":"RSA","correct":"from Crypto.PublicKey import RSA"}],"quickstart":{"code":"from Crypto.Cipher import AES\nfrom Crypto.Random import get_random_bytes\nfrom Crypto.Protocol.KDF import PBKDF2\nimport os\n\n# Simulate a password for key derivation\npassword = os.environ.get('CRYPTO_PASSWORD', 'mysecretpassword').encode('utf-8')\n\n# Generate a random salt\nsalt = get_random_bytes(16)\n\n# Derive a strong key from the password and salt\n# Use default iterations (or a high number like 1000000)\nkey = PBKDF2(password, salt, dkLen=32) # 32 bytes for AES-256\n\n# The data to encrypt\ndata = b\"This is a super secret message.\"\n\n# Encrypt with AES GCM\n# A nonce is automatically generated by AES.new() in GCM mode\ncipher = AES.new(key, AES.MODE_GCM)\nciphertext, tag = cipher.encrypt_and_digest(data)\nnonce = cipher.nonce\n\nprint(f\"Original: {data}\")\nprint(f\"Salt: {salt.hex()}\")\nprint(f\"Nonce: {nonce.hex()}\")\nprint(f\"Ciphertext: {ciphertext.hex()}\")\nprint(f\"Tag: {tag.hex()}\")\n\n# --- Decryption ---\n# Re-derive the key using the same password and salt\ndecryption_key = PBKDF2(password, salt, dkLen=32)\n\n# Create a new cipher object for decryption using the received key and nonce\ndecrypt_cipher = AES.new(decryption_key, AES.MODE_GCM, nonce=nonce)\n\n# Decrypt and verify\ntry:\n    plaintext = decrypt_cipher.decrypt_and_verify(ciphertext, tag)\n    print(f\"Decrypted: {plaintext}\")\nexcept ValueError:\n    print(\"Decryption failed or message was tampered with!\")","lang":"python","description":"This quickstart demonstrates symmetric encryption and decryption using AES in GCM (Galois/Counter Mode), an authenticated encryption mode. It shows how to derive a key from a password using PBKDF2, generate a random salt and nonce, encrypt data, and then decrypt and verify its integrity."},"warnings":[{"fix":"Always install `pycryptodome` in a dedicated virtual environment. If a project requires coexistence with `PyCrypto`, install `pycryptodomex` instead, which uses the `Cryptodome` namespace.","message":"PyCryptodome uses the `Crypto` top-level package name. Installing `pycryptodome` in an environment that also has the unmaintained `PyCrypto` library will cause import conflicts and unexpected behavior. Always use virtual environments and ensure only one is installed.","severity":"breaking","affected_versions":"All versions"},{"fix":"Upgrade to Python 3.7 or newer, or pin `pycryptodome` to a version older than 3.22.0 (e.g., `pycryptodome<3.22.0`).","message":"Python 3.6 support was removed in version 3.22.0. Users on Python 3.6 will need to pin to an older version of PyCryptodome (e.g., <3.22.0).","severity":"breaking","affected_versions":">=3.22.0"},{"fix":"Explicitly specify the desired mode, e.g., `AES.new(key, AES.MODE_GCM)` or `AES.new(key, AES.MODE_CBC)`. If ECB is intentionally needed, use `AES.new(key, AES.MODE_ECB)`.","message":"ECB mode is no longer the default for symmetric ciphers. Calling `AES.new(key)` will now fail. ECB is not semantically secure and should generally be avoided.","severity":"breaking","affected_versions":"All versions, compared to PyCrypto"},{"fix":"Use dedicated modules for public-key operations: `Crypto.Cipher.PKCS1_OAEP` for RSA encryption/decryption, `Crypto.Signature.pkcs1_15` or `Crypto.Signature.pss` for RSA signing, and `Crypto.Signature.DSS` for DSA signing.","message":"Several methods like `sign()`, `verify()`, `encrypt()`, `decrypt()`, `blind()`, `unblind()` were removed from public key objects (RSA, DSA, ElGamal) due to security concerns or maintenance difficulties.","severity":"breaking","affected_versions":"All versions, compared to PyCrypto"},{"fix":"Upgrade to version 3.19.1 or newer to mitigate potential side-channel attacks on OAEP decryption.","message":"A side-channel leakage vulnerability (Manger attack) in OAEP decryption was fixed.","severity":"gotcha","affected_versions":"<3.19.1"},{"fix":"Upgrade to version 3.22.0 or newer if using RC4 with potentially large datasets. Consider migrating away from RC4 as it is generally considered insecure for modern applications.","message":"An infinite loop bug affecting RC4 ciphers when processing data larger than 4GB was resolved.","severity":"gotcha","affected_versions":"<3.22.0"},{"fix":"Upgrade to version 3.23.0 or newer to ensure correct state management for HashEdDSA and Ed448 operations.","message":"For HashEdDSA and Ed448, the `sign()` and `verify()` methods incorrectly modified the state of the XOF (eXtendable Output Function).","severity":"gotcha","affected_versions":"<3.23.0"}],"env_vars":null,"last_verified":"2026-05-12T15:09:18.528Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"First, uninstall any existing `pycrypto` or `crypto` packages: `pip uninstall pycrypto crypto`. Then, install `pycryptodome`: `pip install pycryptodome`. Ensure your imports use `from Crypto.Cipher import AES` (or similar) as intended by `pycryptodome`.","cause":"This error typically occurs when the `pycryptodome` library is not installed, or there is a conflict with the older `pycrypto` library, or due to case sensitivity issues on Windows where `crypto` might be installed instead of `Crypto` in the site-packages.","error":"ModuleNotFoundError: No module named 'Crypto'"},{"fix":"Uninstall the older `pycrypto` package: `pip uninstall pycrypto`.","cause":"This error, often seen with `strxor`, arises when both the old `pycrypto` and `pycryptodome` packages are installed concurrently, causing module interference.","error":"TypeError: argument 2 must be bytes, not bytearray"},{"fix":"Ensure you have necessary build tools installed (e.g., `build-essential` on Debian/Ubuntu, Xcode Command Line Tools on macOS, or Visual C++ Build Tools on Windows). Also, ensure your Python development headers are installed (e.g., `python3-dev` on Debian/Ubuntu). It's also recommended to upgrade pip: `pip install --upgrade pip`.","cause":"This installation error usually indicates missing system-level build tools (like C compilers), missing Python development headers, or an incompatible Python version on your system.","error":"ERROR: Failed building wheel for pycryptodome"},{"fix":"Verify that the ciphertext has not been altered, the correct key is being used, and the padding scheme (e.g., PKCS7, none) and mode of operation (e.g., CBC, GCM) specified during decryption precisely match those used during encryption.","cause":"This error during decryption typically means the provided ciphertext length does not match the expected block size or padding scheme, often due to corrupted data, incorrect key usage, or improper padding removal settings.","error":"ValueError: Ciphertext with incorrect length"}],"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.07,"mem_mb":1.6,"disk_size":"26.3M"},{"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.07,"mem_mb":1.6,"disk_size":"27M"},{"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.1,"mem_mb":1.9,"disk_size":"29.2M"},{"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.07,"mem_mb":1.9,"disk_size":"30M"},{"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.07,"mem_mb":1.9,"disk_size":"20.9M"},{"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.1,"mem_mb":1.9,"disk_size":"22M"},{"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.07,"mem_mb":2,"disk_size":"20.5M"},{"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.1,"mem_mb":1.8,"disk_size":"22M"},{"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.1,"mem_mb":1.6,"disk_size":"25.8M"},{"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.09,"mem_mb":1.6,"disk_size":"27M"}]},"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}]}}