python-pkcs11 provides Python bindings for PKCS#11, a standard for cryptographic tokens. It allows interaction with hardware security modules (HSMs) and smart cards using a native Python API. The library is actively maintained with frequent minor releases, ensuring compatibility with the latest Python versions and addressing specific token behaviors. The current version is 0.9.4.
pip install python-pkcs11Verified import paths — ran on the pinned version, not inferred.
This quickstart demonstrates how to load a PKCS#11 shared library and list available slots. You must have a PKCS#11 library installed on your system (e.g., SoftHSM2 for testing, or a hardware vendor's driver). Set the `PKCS11_LIBRARY` environment variable to its path.
Install a suitable PKCS#11 implementation for your operating system (e.g., `sudo apt install softhsm2` on Ubuntu) and provide its path to `pkcs11.lib()`.
If you relied on ECB for AES key wrapping, explicitly specify `pkcs11.Mechanism.AES_ECB_ENCRYPT_DATA` or update your code to use the new standard mechanisms like `AES_KEY_WRAP`.
Ensure your token's firmware is up-to-date. If issues persist, consider fetching attributes one by one using specific attribute types if the bundled mitigation doesn't resolve the problem for your specific hardware.
Review the documentation for managing multiple `pkcs11.lib()` instances and their sessions if your application requires interacting with more than one PKCS#11 shared library concurrently.
Verify the absolute path to your PKCS#11 shared library. Ensure it exists, is readable, and matches your Python interpreter's architecture (e.g., 64-bit Python with 64-bit library). For Linux, check `LD_LIBRARY_PATH` or `/etc/ld.so.conf`.
Run `pip install python-pkcs11` to install the library.
Ensure your hardware token is properly inserted and initialized. For SoftHSM2, ensure you have created and initialized a token (e.g., `softhsm2-util --init-token --slot 0 --label 'my-token' --pin 1234 --so-pin 123456`).
Always check if the result of `get_token()` or `get_slot()` is `None` before attempting to use it. For example: `token = lib.get_token(token_label='my-token'); if token: session = token.open()`.