pyDes
pyDes is a pure Python implementation of the DES and Triple-DES encryption algorithms. It is designed for portability across Python versions rather than performance, making it suitable for simple, small-scale encryption tasks. The current version, 2.0.1, was released on April 28, 2010, and the project is no longer actively maintained.
Common errors
-
ValueError: Invalid DES key size. Key must be exactly 8 bytes long.
cause The encryption key provided to `pyDes.des` was not exactly 8 bytes in length. For `pyDes.triple_des`, the key must be 16 or 24 bytes.fixEnsure the key is a byte string of the correct length: 8 bytes for DES, or 16/24 bytes for Triple DES. Example: `key = b"8bytekey"`. -
ValueError: Data must be a multiple of 8 bytes in length. Use padmode=PAD_PKCS5 or set the pad character.
cause The input data for encryption or decryption was not a multiple of 8 bytes, and no padding mode or character was specified.fixInitialize the `des` or `triple_des` object with `padmode=pyDes.PAD_PKCS5` to automatically handle padding. Example: `k = pyDes.des(key, pyDes.CBC, iv, padmode=pyDes.PAD_PKCS5)`. -
TypeError: Can't convert 'bytes' object to str implicitly
cause Attempting to concatenate or mix Python 3 `bytes` objects (returned by `encrypt`/`decrypt`) with `str` objects, or passing a `str` where `bytes` is expected.fixExplicitly convert `bytes` to `str` using `.decode('utf-8')` for display/string operations, and `str` to `bytes` using `.encode('utf-8')` before passing to encryption functions. Ensure all inputs to pyDes are `bytes` type.
Warnings
- breaking Python 2 vs. Python 3 string handling: pyDes expects bytes for all key, IV, and data arguments. In Python 2, `str` was implicitly bytes, but in Python 3, explicit byte strings (`b"..."`) must be used. Passing regular Python 3 strings will lead to `TypeError` or `ValueError`.
- gotcha Key length requirements: DES requires an 8-byte key. Triple DES requires either a 16-byte key (DES-EDE2) or a 24-byte key (DES-EDE3). Providing an incorrect key length will raise a `ValueError`.
- gotcha Data padding is crucial: Encryption/decryption operates on 8-byte blocks. If input data is not a multiple of 8 bytes, it must be padded. Failure to pad, or incorrect padding, leads to `ValueError: Data must be a multiple of 8 bytes in length.` The recommended padding mode is `pyDes.PAD_PKCS5` as it is unambiguously reversible.
- deprecated Security vulnerability: DES and Triple DES (3DES) are cryptographically weak and considered obsolete for modern security requirements due to short key lengths and susceptibility to various attacks. The default ECB mode is particularly insecure as it leaks patterns in the plaintext.
Install
-
pip install pyDes
Imports
- des
import pyDes des_cipher = pyDes.des(key, mode, iv, pad, padmode)
- triple_des
import pyDes tdes_cipher = pyDes.triple_des(key, mode, iv, pad, padmode)
Quickstart
import pyDes
# For Python 3, all strings must be converted to bytes
# For DES, key must be exactly 8 bytes
# For Triple DES, key must be 16 or 24 bytes
# IV (Initialization Vector) must be 8 bytes for CBC mode
key_des = b"DESCRYPT"
key_3des_2key = b"0123456789ABCDEF"
key_3des_3key = b"0123456789ABCDEFabcdefgh"
data = b"Please encrypt my data. It needs to be padded."
# --- Single DES Example (CBC mode, PKCS5 padding) ---
try:
# DES encryption object
k_des = pyDes.des(key_des, pyDes.CBC, b"\0\0\0\0\0\0\0\0", pad=None, padmode=pyDes.PAD_PKCS5)
encrypted_des = k_des.encrypt(data)
print(f"Encrypted DES: {encrypted_des!r}")
decrypted_des = k_des.decrypt(encrypted_des)
print(f"Decrypted DES: {decrypted_des!r}")
assert decrypted_des == data
except ValueError as e:
print(f"DES Error: {e}")
# --- Triple DES Example (2-Key, CBC mode, PKCS5 padding) ---
try:
# Triple DES encryption object (2-key)
k_3des_2key = pyDes.triple_des(key_3des_2key, pyDes.CBC, b"\0\0\0\0\0\0\0\0", pad=None, padmode=pyDes.PAD_PKCS5)
encrypted_3des_2key = k_3des_2key.encrypt(data)
print(f"Encrypted 3DES (2-key): {encrypted_3des_2key!r}")
decrypted_3des_2key = k_3des_2key.decrypt(encrypted_3des_2key)
print(f"Decrypted 3DES (2-key): {decrypted_3des_2key!r}")
assert decrypted_3des_2key == data
except ValueError as e:
print(f"3DES (2-key) Error: {e}")
# --- Triple DES Example (3-Key, ECB mode, PKCS5 padding) ---
try:
# Triple DES encryption object (3-key)
k_3des_3key = pyDes.triple_des(key_3des_3key, pyDes.ECB, pad=None, padmode=pyDes.PAD_PKCS5)
encrypted_3des_3key = k_3des_3key.encrypt(data)
print(f"Encrypted 3DES (3-key): {encrypted_3des_3key!r}")
decrypted_3des_3key = k_3des_3key.decrypt(encrypted_3des_3key)
print(f"Decrypted 3DES (3-key): {decrypted_3des_3key!r}")
assert decrypted_3des_3key == data
except ValueError as e:
print(f"3DES (3-key) Error: {e}")