PKCS#11 for Smart Cards

Using PKCS#11 (Cryptoki) to access smart card cryptographic functions: session management, key operations, and signing workflows.

| 4 min read

PKCS#11 for Smart Cards

PKCS#11 (also known as Cryptoki, from Cryptographic Token Interface) is the de facto standard API for communicating with hardware cryptographic tokens — including smart cards, HSMs, and secure elements. Defined by RSARSACryptographyPublic-key algorithm for smart card signatures and key exchange.Click to view → Laboratories and now maintained by OASIS, PKCS#11 v2.40 and v3.0 provide a language-neutral specification implemented by vendor middleware and open-source libraries alike.

Understanding the Cryptoki object model is essential for anyone building applications that use smart card private keys without ever extracting them from the card.

The Slot / Token / Session Model

Cryptoki organises hardware into a three-level hierarchy:

Level Concept Analogy
Slot A physical or logical reader Card reader socket
Token A smart card inserted in a slot The card itself
Session An open channel to a token A connected TCP socket

A single process can open multiple sessions to the same token simultaneously, but only one session at a time may hold the SO (Security Officer) role. User-level sessions authenticate with a PIN via C_Login; the session inherits the token's access permissions once authenticated.

Key Objects and Attributes

Every cryptographic object on a PKCS#11 token — key pair, certificate, or data — is represented by a set of typed attributes. Important attributes include:

Attribute Token Meaning
CKA_CLASS Object class: CKO_PRIVATE_KEY, CKO_PUBLIC_KEY, CKO_CERTIFICATE
CKA_TOKEN CK_TRUE = persisted in non-volatile memory, CK_FALSE = session object
CKA_SENSITIVE Private key may never be extracted in plaintext
CKA_EXTRACTABLE Key can be wrapped out (should be CK_FALSE on smart cards)
CKA_SIGN Key may be used for C_Sign
CKA_DECRYPT Key may be used for C_Decrypt
CKA_ID Byte array linking key pair to its certificate

On a typical smart card, private key objects carry CKA_SENSITIVE=TRUE and CKA_EXTRACTABLE=FALSE, meaning the key bytes never leave the chip.

Core Cryptoki Functions

Signing — C_Sign

// 1. Open session and log in
C_OpenSession(slotId, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &hSession);
C_Login(hSession, CKU_USER, (CK_UTF8CHAR_PTR)"123456", 6);

// 2. Find the private key by CKA_ID
CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
CK_ATTRIBUTE tmpl[] = {
    { CKA_CLASS, &keyClass, sizeof(keyClass) },
    { CKA_ID,    keyId,     keyIdLen }
};
C_FindObjectsInit(hSession, tmpl, 2);
C_FindObjects(hSession, &hKey, 1, &found);
C_FindObjectsFinal(hSession);

// 3. Sign a SHA-256 digest
CK_MECHANISM mech = { CKM_RSA_PKCS, NULL, 0 };
C_SignInit(hSession, &mech, hKey);
C_Sign(hSession, digest, 32, sig, &sigLen);

The card receives a single APDU command wrapping the digest; the private key never leaves the secure element.

Encryption — C_Encrypt / C_Decrypt

C_Encrypt uses a public key or symmetric key to encrypt data. For RSA key exchange, the typical mechanism is CKM_RSA_PKCS_OAEP. Decryption with C_Decrypt is the critical path: the private key on the card unwraps a session key that the host then uses for bulk AESAESCryptographyNIST symmetric block cipher for smart card encryption.Click to view → decryption.

Common PKCS#11 Libraries

Library Platform Notes
OpenSC opensc-pkcs11.so Linux, macOS, Windows Open-source; supports most ISO 7816ISO 7816StandardPrimary standard for contact smart cards.Click to view → cards
Yubico PIVPIVIdentityUS federal identity card standard.Click to view → PKCS#11 Cross-platform YubiKey 4/5 specific
ActivClient Windows US government CACCACIdentityUS DoD identification smart card.Click to view →/PIV middleware
Gemalto SafeNet Cross-platform Commercial; supports IDPrime, Luna HSMHSMSecurityPhysical device for key management.Click to view →
NSS libsoftokn3 Mozilla products Software token fallback

ISO 7816 Mapping

At the transport layer, each C_Sign call translates to a PSO: COMPUTE DIGITAL SIGNATURE APDUAPDUProtocolCommunication unit between card and reader.Click to view → (INS 0x2A, P1 0x9E, P2 0x9A). Use the APDU Builder to construct and test APDU sequences manually.

Security Considerations

  • PIN caching: Never cache PIN in application memory beyond the session lifetime.
  • Thread safety: PKCS#11 is not thread-safe by default; use CKF_OS_LOCKING_OK flag.
  • Mechanism negotiation: Always verify C_GetMechanismInfo before assuming a mechanism is available — different card models support different algorithm sets.
  • Session management: Always call C_CloseSession and C_Finalize to release card resources; leaked sessions can lock the token.

For a hands-on introduction to smart card command structure, see the APDU Builder tool or Understanding APDU Commands.

자주 묻는 질문

Our guides cover a range of experience levels. Getting Started guides introduce smart card fundamentals. Security guides address Common Criteria certification and key management. Programming guides target developers working with APDU commands, JavaCard applets, and GlobalPlatform card management.