PyKCS11 - Python PKCS#11 Wrapper

1.5.18 · active · verified Thu Apr 16

PyKCS11 is a comprehensive Python wrapper for the PKCS#11 standard, enabling interaction with Hardware Security Modules (HSMs) and smart cards. It provides Python bindings for PKCS#11 functions, constants, and structures. The library is actively maintained with periodic releases, typically several times a year, with the current stable version being 1.5.18.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to load a PKCS#11 library, open a session, log in with a user PIN, and list objects (keys, certificates) present on the token. Replace `PKCS11_LIB_PATH` and `PKCS11_USER_PIN` with your actual PKCS#11 library path and PIN. For testing, SoftHSMv2 is a common choice.

import PyKCS11
import os

# Path to your PKCS#11 shared library (e.g., softhsm2.so, libeToken.so)
# For testing, consider installing SoftHSMv2.
pkcs11_lib_path = os.environ.get('PKCS11_LIB_PATH', '/usr/local/lib/softhsm/libsofthsm2.so')
user_pin = os.environ.get('PKCS11_USER_PIN', '1234')

try:
    # Initialize the PyKCS11 library wrapper
    pkcs11 = PyKCS11.PyKCS11Lib()
    pkcs11.load(pkcs11_lib_path)

    # Get a list of available slots with a token present
    slots = pkcs11.getSlotList(tokenPresent=True)
    if not slots:
        print("No PKCS#11 slots with tokens found. Ensure your HSM/smart card is connected and configured.")
        exit()

    # Open a session with the first available slot
    session = pkcs11.openSession(slots[0])

    # Log in to the token (required for most operations)
    session.login(user_pin)

    print(f"Successfully logged into slot {slots[0]} using PIN.")

    # Example: Find and list objects (e.g., keys, certificates)
    objects = session.findObjects()
    print(f"\nFound {len(objects)} objects in the token:")
    for obj in objects:
        # Attempt to get CKA_CLASS and CKA_LABEL attributes gracefully
        attributes = session.getAttributeValue(obj, [PyKCS11.CKA_CLASS, PyKCS11.CKA_LABEL])
        obj_class = next((attr for attr in attributes if attr.type == PyKCS11.CKA_CLASS), None)
        obj_label = next((attr for attr in attributes if attr.type == PyKCS11.CKA_LABEL), None)
        
        class_name = pkcs11.constantToString(obj_class.value, PyKCS11.CKF_CLASS_DEFINED) if obj_class else 'N/A'
        label = obj_label.value if obj_label else 'N/A'
        print(f"  - Class: {class_name}, Label: {label}")

finally:
    # Ensure logout, close session, and unload library in a finally block
    if 'session' in locals() and session:
        try:
            session.logout()
            session.closeSession()
            print("\nLogged out and session closed.")
        except PyKCS11.PyKCS11Error as e:
            print(f"Error during cleanup: {e}")
    if 'pkcs11' in locals() and pkcs11:
        try:
            pkcs11.unload()
            print("PKCS#11 library unloaded.")
        except PyKCS11.PyKCS11Error as e:
            print(f"Error during library unload: {e}")

view raw JSON →