pysodium
pysodium is a Python wrapper for the `libsodium` cryptography library, providing high-level cryptographic primitives for tasks like encryption, decryption, signatures, and key derivation. The library aims to offer a simple interface, often aligning with the PyNaCl API, and handles buffer management for ease of use in Python. It is currently at version 0.7.18 and receives regular updates, with new features and security fixes introduced periodically.
Common errors
-
ModuleNotFoundError: No module named 'pysodium'
cause The pysodium Python package has not been installed in your current environment.fixRun `pip install pysodium` to install the package. -
OSError: libsodium.so: cannot open shared object file: No such file or directory
cause The underlying `libsodium` C library, which `pysodium` wraps, is not installed or cannot be found in your system's library paths.fixInstall the `libsodium` development package for your operating system (e.g., `sudo apt-get install libsodium-dev` on Debian/Ubuntu, `brew install libsodium` on macOS). For Windows, you'll need to download and install the pre-compiled `libsodium` binaries or compile from source, ensuring the `libsodium.dll` is discoverable by Python (e.g., in PATH). -
ValueError: Decryption failed
cause This error, often specifically `pysodium.exceptions.BadSignatureError`, indicates that the ciphertext has been tampered with, or the key/nonce used for decryption does not match those used for encryption. This is a deliberate security feature of authenticated encryption.fixEnsure the `key`, `nonce`, and `ciphertext` are exactly the same as those used during encryption. Verify that no data corruption or malicious modification has occurred during transmission or storage. If using public-key cryptography, ensure the correct sender's public key and receiver's secret key are used.
Warnings
- breaking Version 0.7.17 fixed a security vulnerability where `crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX`, `crypto_aead_aegis128l_MESSAGEBYTES_MAX`, and `crypto_aead_aegis256_MESSAGEBYTES_MAX` were set to insecurely large values. All users should upgrade to 0.7.17 or later to mitigate potential security risks related to message size limits.
- gotcha pysodium is a wrapper for the `libsodium` C library. You *must* have `libsodium` installed on your system for `pysodium` to work. The `pip install pysodium` command only installs the Python bindings, not the underlying C library.
- gotcha Prior to v0.7.15, some `keygen()` functions in `pysodium` incorrectly returned the size (e.g., 32 for a 32-byte key) instead of a success/fail indicator (0 or 1). Code that checked these return values for success might have exhibited incorrect behavior if they expected a boolean-like result.
Install
-
pip install pysodium
Imports
- pysodium
import pysodium
Quickstart
import pysodium
import os
# --- Secret-key encryption (Symmetric) ---
# Generate a random 32-byte secret key
secret_key = pysodium.randombytes(pysodium.crypto_secretbox_KEYBYTES)
# Generate a unique 24-byte nonce for each message (can be public)
nonce = pysodium.randombytes(pysodium.crypto_secretbox_NONCEBYTES)
message = b"This is a super secret message for Bob."
# Encrypt the message
ciphertext = pysodium.crypto_secretbox(message, nonce, secret_key)
print(f"Original message: {message.decode()}")
print(f"Ciphertext (hex): {ciphertext.hex()}")
# Decrypt the message
try:
decrypted_message = pysodium.crypto_secretbox_open(ciphertext, nonce, secret_key)
print(f"Decrypted message: {decrypted_message.decode()}")
except pysodium.exceptions.BadSignatureError:
print("Decryption failed: Message tampered or incorrect key/nonce.")
# --- Public-key cryptography (Asymmetric) ---
# Generate a key pair for Alice
alice_public_key, alice_secret_key = pysodium.crypto_box_keypair()
# Generate a key pair for Bob
bob_public_key, bob_secret_key = pysodium.crypto_box_keypair()
print(f"\nAlice's Public Key: {alice_public_key.hex()}")
print(f"Bob's Public Key: {bob_public_key.hex()}")