PKCS#11 for Smart Cards
Using PKCS#11 (Cryptoki) to access smart card cryptographic functions: session management, key operations, and signing workflows.
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_OKflag. - Mechanism negotiation: Always verify
C_GetMechanismInfobefore assuming a mechanism is available — different card models support different algorithm sets. - Session management: Always call
C_CloseSessionandC_Finalizeto 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.