Python Bindings for Libsodium (libnacl)
libnacl provides Python bindings for the high-speed Networking and Cryptography library (NaCl), specifically leveraging libsodium via ctypes. It aims to offer direct access to libsodium's functions while maintaining extensive documentation and portability. The library supports both low-level cryptographic primitives and higher-level Pythonic encryption classes. It is currently at version 2.1.0 and is actively maintained.
Common errors
-
OSError: Could not locate nacl lib, searched for libsodium.
cause The underlying `libsodium` C library is not installed on the system or `libnacl` cannot find it in standard library paths.fixInstall `libsodium` via your system's package manager. For Debian/Ubuntu, use `sudo apt-get install libsodium-dev`. Ensure the library is accessible in your system's `LD_LIBRARY_PATH` (Linux) or `PATH` (Windows) if installed in a non-standard location. -
'nacl' __virtual__ returned False: libnacl import error, perhaps missing python libnacl package or should update.
cause This error often occurs when `libnacl` is installed in the Python environment, but it fails to load the underlying `libsodium` C library, or there's a version mismatch/corruption.fixFirst, ensure `libsodium` is correctly installed on your system (see above fix). Then, try reinstalling `libnacl` in your Python environment: `pip uninstall libnacl && pip install libnacl`. -
libnacl.exceptions.BadSignatureError: Signature was forged or otherwise corrupt.
cause This exception is raised when the integrity check of an encrypted message fails, indicating that the ciphertext or its associated authentication tag has been altered, or an incorrect key/nonce was used during decryption.fixVerify that the correct secret key, public key, and nonce (if applicable) are being used for decryption. Ensure the ciphertext has not been tampered with in transit. This error is a security feature, indicating a failed authenticity check.
Warnings
- breaking When using raw `crypto_secretbox` functions directly, specific padding requirements (e.g., zero-padding for the first 32 bytes) might be necessary due to underlying NaCl design for MAC key generation. While higher-level `libnacl` wrappers may handle this, direct low-level usage might break if not accounted for.
- gotcha Nonce reuse with the same key pair is a critical security vulnerability that can compromise encrypted data. `libnacl` generates a random nonce if not explicitly provided to encryption functions, but manual nonce management requires extreme care.
- gotcha `libnacl` is a Python ctypes wrapper, meaning it requires the `libsodium` C library to be installed on the host system. Installing `libnacl` via `pip` only installs the Python package, not the C library.
Install
-
pip install libnacl
Imports
- SecretKey
from libnacl.public import SecretKey
- Box
from libnacl.public import Box
- SealedBox
from libnacl.sealed import SealedBox
- crypto_secretbox
import libnacl libnacl.crypto_secretbox(...)
- salsa_key
import libnacl.utils libnacl.utils.salsa_key()
Quickstart
import libnacl.public
# Define a message to send (must be bytes)
msg = b'You\'ve got two empty halves of coconut and you\'re bangin\' \'em together.'
# Generate the key pairs for Alice and Bob
bob = libnacl.public.SecretKey()
alice = libnacl.public.SecretKey()
# Create Box objects representing the combination of sender's secret key and receiver's public key
bob_box = libnacl.public.Box(bob.sk, alice.pk)
alice_box = libnacl.public.Box(alice.sk, bob.pk)
# Bob encrypts a message for Alice
bob_ctxt = bob_box.encrypt(msg)
# Alice decrypts the message from Bob
bclear = alice_box.decrypt(bob_ctxt)
print(f"Original message: {msg}")
print(f"Decrypted message from Bob: {bclear}")
# Alice encrypts a message for Bob
alice_ctxt = alice_box.encrypt(msg)
# Bob decrypts the message from Alice
aclear = bob_box.decrypt(alice_ctxt)
print(f"Decrypted message from Alice: {aclear}")
assert msg == bclear
assert msg == aclear