{"id":2674,"library":"pyaes","title":"PyAES: Pure Python AES Implementation","description":"PyAES provides a pure-Python implementation of the Advanced Encryption Standard (AES) block cipher, along with common modes of operation like CBC, CTR, and OFB. Currently at version 1.6.1, it offers a lightweight cryptographic option for environments where C extensions are not feasible or desired. Its release cadence is low, with updates typically addressing bug fixes or minor enhancements.","status":"active","version":"1.6.1","language":"en","source_language":"en","source_url":"https://github.com/ricmoo/pyaes","tags":["encryption","cryptography","aes","pure-python","cipher"],"install":[{"cmd":"pip install pyaes","lang":"bash","label":"Install PyAES"}],"dependencies":[],"imports":[{"symbol":"AESModeOfOperationCBC","correct":"from pyaes import AESModeOfOperationCBC"},{"symbol":"AESModeOfOperationCTR","correct":"from pyaes import AESModeOfOperationCTR"},{"note":"Use this for the raw block cipher; typically prefer mode-of-operation classes for common use cases.","symbol":"AES","correct":"from pyaes import AES"}],"quickstart":{"code":"import pyaes\nimport os\n\n# AES in CBC mode (with default zero-padding)\nkey = os.urandom(32) # 256-bit key\niv = os.urandom(16)  # 128-bit Initialization Vector\n\naes_cbc_encrypt = pyaes.AESModeOfOperationCBC(key, iv=iv)\nplaintext = b\"This is some plaintext to encrypt. It will be zero-padded if not a multiple of 16 bytes.\"\nciphertext = aes_cbc_encrypt.encrypt(plaintext)\n\n# Decrypt using a new AES object with the same key and IV\naes_cbc_decrypt = pyaes.AESModeOfOperationCBC(key, iv=iv)\ndecrypted_text = aes_cbc_decrypt.decrypt(ciphertext)\n\nprint(f\"Original: {plaintext}\")\nprint(f\"Encrypted: {ciphertext.hex()}\")\nprint(f\"Decrypted: {decrypted_text}\")\n\nassert decrypted_text == plaintext\n","lang":"python","description":"This example demonstrates encrypting and decrypting data using AES in CBC mode with a 256-bit key. It highlights the use of `AESModeOfOperationCBC` and the necessity of providing a unique IV for each encryption operation. PyAES uses zero-padding by default if the plaintext length is not a multiple of the block size."},"warnings":[{"fix":"Ensure `key` is 16, 24, or 32 bytes long, and `iv` (for CBC/CTR/OFB) is 16 bytes long. Use `os.urandom()` for cryptographically secure random values.","message":"AES key lengths must be 16, 24, or 32 bytes (for AES-128, AES-192, AES-256 respectively). Initialization Vector (IV) for CBC mode must be 16 bytes. Providing incorrect lengths will result in errors or insecure operation.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure you are using version 1.6.0 or higher for reliable stream API functionality. Review code that interacted with the stream API in 1.5.0 as workarounds may no longer be necessary or compatible.","message":"The stream API (e.g., `encrypt_stream`, `decrypt_stream`) was broken in version 1.5.0 and fixed in 1.6.0. Users upgrading from 1.5.0 to 1.6.0 will find their stream operations now function correctly, which might be a 'breaking change' if their code had workarounds for the 1.5.0 bug.","severity":"breaking","affected_versions":"1.5.0 (bugged), 1.6.0+"},{"fix":"For robust applications, implement a cryptographically secure padding scheme like PKCS7 or ISO 10126 before encryption and unpadding after decryption, rather than relying on `pyaes`'s default zero-padding.","message":"PyAES uses simple zero-padding by default when input data is not a multiple of the AES block size (16 bytes). This can lead to security vulnerabilities (e.g., padding oracle attacks) or data loss if the original plaintext legitimately ends with null bytes, as zero-padding cannot distinguish between actual nulls and padding nulls.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always generate a new, cryptographically random IV (e.g., `os.urandom(16)`) for every distinct encryption operation with the same key in CBC mode. Store and transmit the IV alongside the ciphertext (it does not need to be secret).","message":"Reusing the same Initialization Vector (IV) with the same key for multiple encryptions in CBC mode significantly compromises confidentiality, making the encryption vulnerable to attacks. A unique, unpredictable IV is crucial for each encryption operation.","severity":"gotcha","affected_versions":"All versions (when using CBC mode)"}],"env_vars":null,"last_verified":"2026-04-10T00:00:00.000Z","next_check":"2026-07-09T00:00:00.000Z"}