### Initialize PKCS11 and Get Module Info Source: https://github.com/peculiarventures/pkcs11js/blob/master/README.md This snippet demonstrates the basic setup for using PKCS11js. It involves loading the PKCS#11 library, initializing the module, and retrieving general information about the PKCS#11 module, slots, tokens, and mechanisms. It also shows how to open and manage a session, including login and logout. ```javascript var pkcs11js = require("pkcs11js"); var pkcs11 = new pkcs11js.PKCS11(); pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); pkcs11.C_Initialize(); try { // Getting info about PKCS11 Module var module_info = pkcs11.C_GetInfo(); // Getting list of slots var slots = pkcs11.C_GetSlotList(true); var slot = slots[0]; // Getting info about slot var slot_info = pkcs11.C_GetSlotInfo(slot); // Getting info about token var token_info = pkcs11.C_GetTokenInfo(slot); // Getting info about Mechanism var mechs = pkcs11.C_GetMechanismList(slot); var mech_info = pkcs11.C_GetMechanismInfo(slot, mechs[0]); var session = pkcs11.C_OpenSession(slot, pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION); // Getting info about Session var info = pkcs11.C_GetSessionInfo(session); pkcs11.C_Login(session, 1, "password"); /** * Your app code here */ pkcs11.C_Logout(session); pkcs11.C_CloseSession(session); } catch(e){ console.error(e); } finally { pkcs11.C_Finalize(); } ``` -------------------------------- ### Initializing NSS Crypto Library Source: https://github.com/peculiarventures/pkcs11js/blob/master/README.md This example shows how to initialize the NSS crypto library using `C_Initialize` with custom options, including library parameters. ```APIDOC ## C_Initialize with NSS Options ### Description Initializes the Cryptoki library, supporting standard `CK_C_INITIALIZE_ARGS` and extended NSS formats. The `options` parameter allows for specifying library parameters and flags. ### Method `C_Initialize(options?: InitializationOptions): void` ### Endpoint N/A (Function call) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```javascript const mod = new pkcs11.PKCS11(); mod.load("/usr/local/opt/nss/lib/libsoftokn3.dylib"); mod.C_Initialize({ libraryParameters: "configdir='' certPrefix='' keyPrefix='' secmod='' flags=readOnly,noCertDB,noModDB,forceOpen,optimizeSpace", }); // Your code here mod.C_Finalize(); ``` ### Response #### Success Response (200) Initializes the library. #### Response Example None (void function) ``` -------------------------------- ### Initialize PKCS11js and Get Module Info Source: https://context7.com/peculiarventures/pkcs11js/llms.txt Load the PKCS#11 library and initialize the Cryptoki module. Retrieves and logs basic information about the loaded library. ```javascript const pkcs11js = require("pkcs11js"); // Create PKCS11 instance and load the library const pkcs11 = new pkcs11js.PKCS11(); pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); // Initialize and get module info pkcs11.C_Initialize(); try { const moduleInfo = pkcs11.C_GetInfo(); console.log("Cryptoki Version:", moduleInfo.cryptokiVersion.major + "." + moduleInfo.cryptokiVersion.minor); console.log("Library:", moduleInfo.libraryDescription); // Output: Cryptoki Version: 2.40 // Output: Library: SoftHSM } finally { pkcs11.C_Finalize(); } ``` -------------------------------- ### Create, Update, Get, Copy, and Destroy Objects Source: https://github.com/peculiarventures/pkcs11js/blob/master/README.md Demonstrates the lifecycle management of PKCS#11 objects, including creation, attribute modification, retrieval, copying, and deletion. ```javascript var nObject = pkcs11.C_CreateObject(session, [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_DATA }, { type: pkcs11js.CKA_TOKEN, value: false }, { type: pkcs11js.CKA_PRIVATE, value: false }, { type: pkcs11js.CKA_LABEL, value: "My custom data" }, ]); // Updating label of Object pkcs11.C_SetAttributeValue(session, nObject, [{ type: pkcs11js.CKA_LABEL, value: "My custom data!!!" }]); // Getting attribute value var label = pkcs11.C_GetAttributeValue(session, nObject, [ { type: pkcs11js.CKA_LABEL }, { type: pkcs11js.CKA_TOKEN } ]); console.log(label[0].value.toString()); // My custom data!!! console.log(!!label[1].value[0]); // false // Copying Object var cObject = pkcs11.C_CopyObject(session, nObject, [ { type: pkcs11js.CKA_CLASS}, { type: pkcs11js.CKA_TOKEN}, { type: pkcs11js.CKA_PRIVATE}, { type: pkcs11js.CKA_LABEL}, ]); // Removing Object pkcs11.C_DestroyObject(session, cObject); ``` -------------------------------- ### Manage Slots and Tokens with PKCS11js Source: https://context7.com/peculiarventures/pkcs11js/llms.txt Retrieve a list of available slots, get detailed slot and token information, and query supported cryptographic mechanisms. Requires an initialized PKCS11 instance. ```javascript const pkcs11js = require("pkcs11js"); const pkcs11 = new pkcs11js.PKCS11(); pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); pkcs11.C_Initialize(); try { // Get list of slots with tokens present const slots = pkcs11.C_GetSlotList(true); const slot = slots[0]; // Get slot information const slotInfo = pkcs11.C_GetSlotInfo(slot); console.log("Slot:", slotInfo.slotDescription); console.log("Manufacturer:", slotInfo.manufacturerID); // Get token information const tokenInfo = pkcs11.C_GetTokenInfo(slot); console.log("Token Label:", tokenInfo.label); console.log("Serial Number:", tokenInfo.serialNumber); console.log("Max PIN Length:", tokenInfo.maxPinLen); // Get supported mechanisms const mechanisms = pkcs11.C_GetMechanismList(slot); console.log("Supported mechanisms:", mechanisms.length); // Get mechanism info for AES const mechInfo = pkcs11.C_GetMechanismInfo(slot, pkcs11js.CKM_AES_CBC); console.log("AES Key Size Range:", mechInfo.minKeySize, "-", mechInfo.maxKeySize); } finally { pkcs11.C_Finalize(); } ``` -------------------------------- ### Handle PKCS#11 and Native Errors Source: https://context7.com/peculiarventures/pkcs11js/llms.txt Demonstrates how to catch and differentiate between PKCS#11 errors, native errors, and type errors. Includes examples for both synchronous and asynchronous operations. ```javascript const pkcs11js = require("pkcs11js"); const pkcs11 = new pkcs11js.PKCS11(); pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); try { // This will throw because C_Initialize wasn't called pkcs11.C_Finalize(); } catch (e) { if (e instanceof pkcs11js.Pkcs11Error) { console.log("PKCS#11 Error:", e.message); console.log("Error Code:", e.code); console.log("Method:", e.method); console.log("Native Stack:", e.nativeStack); // Output: PKCS#11 Error: CKR_CRYPTOKI_NOT_INITIALIZED // Output: Error Code: 400 (CKR_CRYPTOKI_NOT_INITIALIZED) } else if (e instanceof pkcs11js.NativeError) { console.log("Native Error:", e.message); } else if (e instanceof TypeError) { console.log("Type Error:", e.message); } } // Async error handling with callbacks pkcs11.C_Initialize(); const slots = pkcs11.C_GetSlotList(true); const session = pkcs11.C_OpenSession(slots[0], pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION); pkcs11.C_Login(session, pkcs11js.CKU_USER, "12345"); pkcs11.C_GenerateKeyPair(session, { mechanism: pkcs11js.CKM_RSA_PKCS_KEY_PAIR_GEN }, [], [], (error, keys) => { if (error) { console.log("Async Error:", error.message); console.log("Error Code:", error.code); // Output: Async Error: CKR_TEMPLATE_INCOMPLETE } }); // Promise-based error handling try { const keys = await pkcs11.C_GenerateKeyPairAsync(session, { mechanism: pkcs11js.CKM_RSA_PKCS_KEY_PAIR_GEN }, [], []); } catch (error) { if (error instanceof pkcs11js.Pkcs11Error) { console.log("Promise Error:", error.message, "Code:", error.code); } } pkcs11.C_Logout(session); pkcs11.C_CloseSession(session); pkcs11.C_Finalize(); ``` -------------------------------- ### Detect Slot Event Source: https://github.com/peculiarventures/pkcs11js/blob/master/README.md This example demonstrates how to use `C_WaitForSlotEvent` to detect when a slot event occurs, such as a token insertion or removal. ```APIDOC ## C_WaitForSlotEvent ### Description Waits for a slot event to occur. This function is useful for detecting token insertion or removal. ### Method `C_WaitForSlotEvent(flags?: number): number | null` ### Endpoint N/A (Function call) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```javascript var pkcs11js = require("pkcs11js"); var pkcs11 = new pkcs11js.PKCS11(); // Need a compliant Cryptoki Version 2.01 or later pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); pkcs11.C_Initialize(); try { const slotId = pkcs11.C_WaitForSlotEvent(pkcs11js.CKF_DONT_BLOCK); if (slotId) { console.log(`Slot ${slotId} has been inserted`); } else { console.log(`No slot event`); } } catch (e) { console.error(e); } finally { pkcs11.C_Finalize(); } ``` ### Response #### Success Response (200) Returns the ID of the slot where the event occurred, or null if no event occurred within the specified timeout (if any). #### Response Example ```json // If a slot is inserted: "Slot 1 has been inserted" // If no slot event: "No slot event" ``` ``` -------------------------------- ### Deriving Key with ECDH Mechanism Source: https://github.com/peculiarventures/pkcs11js/blob/master/README.md This example demonstrates how to derive a key using the ECDH mechanism in pkcs11.js. It involves retrieving the EC point from a public key, then using C_DeriveKey with CKM_ECDH1_DERIVE. ```APIDOC ## C_DeriveKey with CKM_ECDH1_DERIVE ### Description Derives a key using the Elliptic Curve Diffie-Hellman (ECDH) mechanism. ### Method `C_DeriveKey` ### Endpoint N/A (Function call) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```javascript // Receive public data from EC public key var attrs = pkcs11.C_GetAttributeValue(session, publicKeyEC, [{ type: pkcs11js.CKA_EC_POINT }]); var ec = attrs[0].value; var derivedKey = pkcs11.C_DeriveKey( session, { mechanism: pkcs11js.CKM_ECDH1_DERIVE, parameter: { type: pkcs11js.CK_PARAMS_EC_DH, kdf: 2, publicData: ec } }, privateKeyEC, [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_SECRET_KEY }, { type: pkcs11js.CKA_TOKEN, value: false }, { type: pkcs11js.CKA_KEY_TYPE, value: pkcs11js.CKK_AES }, { type: pkcs11js.CKA_LABEL, value: "Derived AES key" }, { type: pkcs11js.CKA_ENCRYPT, value: true }, { type: pkcs11js.CKA_VALUE_LEN, value: 256 / 8 } ] ); ``` ### Response #### Success Response (200) Returns the derived key object. #### Response Example ```json // Derived key object { // ... key attributes ... } ``` ``` -------------------------------- ### Find Objects with Specific Attributes Source: https://github.com/peculiarventures/pkcs11js/blob/master/README.md Searches for PKCS#11 objects based on provided attributes. If no template is set, all objects from the slot are returned. This example filters for data objects and outputs their labels if they are token-bound. ```javascript pkcs11.C_FindObjectsInit(session, [{ type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_DATA }]); var hObject = pkcs11.C_FindObjects(session); while (hObject) { var attrs = pkcs11.C_GetAttributeValue(session, hObject, [ { type: pkcs11js.CKA_CLASS }, { type: pkcs11js.CKA_TOKEN }, { type: pkcs11js.CKA_LABEL } ]); // Output info for objects from token only if (attrs[1].value[0]){ console.log(`Object #${hObject}: ${attrs[2].value.toString()}`); } hObject = pkcs11.C_FindObjects(session); } pkcs11.C_FindObjectsFinal(session); ``` -------------------------------- ### AES-CBC Encryption and Decryption Source: https://context7.com/peculiarventures/pkcs11js/llms.txt Encrypts and decrypts data using AES in CBC mode with PKCS#7 padding. This example demonstrates both single-part and multi-part operations. Ensure the PKCS#11 library is loaded and the user is logged in. ```javascript const pkcs11js = require("pkcs11js"); const pkcs11 = new pkcs11js.PKCS11(); pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); pkcs11.C_Initialize(); const slots = pkcs11.C_GetSlotList(true); const session = pkcs11.C_OpenSession(slots[0], pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION); pkcs11.C_Login(session, pkcs11js.CKU_USER, "12345"); try { // Generate random IV const iv = pkcs11.C_GenerateRandom(session, Buffer.alloc(16)); // Create AES key const aesKey = pkcs11.C_GenerateKey(session, { mechanism: pkcs11js.CKM_AES_KEY_GEN }, [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_SECRET_KEY }, { type: pkcs11js.CKA_VALUE_LEN, value: 32 }, { type: pkcs11js.CKA_ENCRYPT, value: true }, { type: pkcs11js.CKA_DECRYPT, value: true }, ]); const plaintext = Buffer.from("Hello, PKCS#11 world!"); const mechanism = { mechanism: pkcs11js.CKM_AES_CBC_PAD, parameter: iv }; // Encrypt (single-part) pkcs11.C_EncryptInit(session, mechanism, aesKey); const encrypted = pkcs11.C_Encrypt(session, plaintext, Buffer.alloc(1024)); console.log("Encrypted:", encrypted.toString("hex")); // Decrypt (single-part) pkcs11.C_DecryptInit(session, mechanism, aesKey); const decrypted = pkcs11.C_Decrypt(session, encrypted, Buffer.alloc(1024)); console.log("Decrypted:", decrypted.toString()); // Output: Decrypted: Hello, PKCS#11 world! // Multi-part encryption pkcs11.C_EncryptInit(session, mechanism, aesKey); let enc = pkcs11.C_EncryptUpdate(session, Buffer.from("Part 1"), Buffer.alloc(128)); enc = Buffer.concat([enc, pkcs11.C_EncryptUpdate(session, Buffer.from("Part 2"), Buffer.alloc(128))]); enc = Buffer.concat([enc, pkcs11.C_EncryptFinal(session, Buffer.alloc(128))]); console.log("Multi-part encrypted length:", enc.length); } finally { pkcs11.C_Logout(session); pkcs11.C_CloseSession(session); pkcs11.C_Finalize(); } ``` -------------------------------- ### Wrap and Unwrap Keys with PKCS11 JS Source: https://context7.com/peculiarventures/pkcs11js/llms.txt Demonstrates generating a wrapping key, a key to be wrapped, and then performing wrap (export) and unwrap (import) operations using AES key wrap with padding. Ensure the PKCS11 library is loaded and a session is established and logged in. ```javascript const pkcs11js = require("pkcs11js"); const pkcs11 = new pkcs11js.PKCS11(); pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); pkcs11.C_Initialize(); const slots = pkcs11.C_GetSlotList(true); const session = pkcs11.C_OpenSession(slots[0], pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION); pkcs11.C_Login(session, pkcs11js.CKU_USER, "12345"); try { // Generate wrapping key with wrap/unwrap capabilities const wrappingKey = pkcs11.C_GenerateKey(session, { mechanism: pkcs11js.CKM_AES_KEY_GEN }, [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_SECRET_KEY }, { type: pkcs11js.CKA_VALUE_LEN, value: 16 }, { type: pkcs11js.CKA_WRAP, value: true }, { type: pkcs11js.CKA_UNWRAP, value: true }, { type: pkcs11js.CKA_EXTRACTABLE, value: true }, ]); // Generate key to be wrapped const keyToWrap = pkcs11.C_GenerateKey(session, { mechanism: pkcs11js.CKM_AES_KEY_GEN }, [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_SECRET_KEY }, { type: pkcs11js.CKA_VALUE_LEN, value: 16 }, { type: pkcs11js.CKA_ENCRYPT, value: true }, { type: pkcs11js.CKA_DECRYPT, value: true }, { type: pkcs11js.CKA_EXTRACTABLE, value: true }, ]); const mechanism = { mechanism: pkcs11js.CKM_AES_KEY_WRAP_PAD }; // Wrap (export) the key const wrappedKey = pkcs11.C_WrapKey(session, mechanism, wrappingKey, keyToWrap, Buffer.alloc(1024)); console.log("Wrapped key length:", wrappedKey.length); console.log("Wrapped key:", wrappedKey.toString("hex")); // Unwrap (import) the key const unwrappedKey = pkcs11.C_UnwrapKey(session, mechanism, wrappingKey, wrappedKey, [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_SECRET_KEY }, { type: pkcs11js.CKA_KEY_TYPE, value: pkcs11js.CKK_AES }, { type: pkcs11js.CKA_ENCRYPT, value: true }, { type: pkcs11js.CKA_DECRYPT, value: true }, ]); console.log("Unwrapped key handle:", unwrappedKey.toString("hex")); } finally { pkcs11.C_Logout(session); pkcs11.C_CloseSession(session); pkcs11.C_Finalize(); } ``` -------------------------------- ### Manage PKCS11 Objects Source: https://context7.com/peculiarventures/pkcs11js/llms.txt Demonstrates creating, updating, retrieving attributes, finding, copying, and destroying data objects on a PKCS11 token. Ensure the PKCS11 library is loaded and a session is established and logged in before use. ```javascript const pkcs11js = require("pkcs11js"); const pkcs11 = new pkcs11js.PKCS11(); pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); pkcs11.C_Initialize(); const slots = pkcs11.C_GetSlotList(true); const session = pkcs11.C_OpenSession(slots[0], pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION); pkcs11.C_Login(session, pkcs11js.CKU_USER, "12345"); try { // Create a data object const dataObject = pkcs11.C_CreateObject(session, [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_DATA }, { type: pkcs11js.CKA_TOKEN, value: false }, { type: pkcs11js.CKA_PRIVATE, value: false }, { type: pkcs11js.CKA_LABEL, value: "My custom data" }, { type: pkcs11js.CKA_VALUE, value: Buffer.from("secret data") }, ]); console.log("Created object:", dataObject.toString("hex")); // Update object attributes pkcs11.C_SetAttributeValue(session, dataObject, [ { type: pkcs11js.CKA_LABEL, value: "Updated label" } ]); // Get object attributes const attrs = pkcs11.C_GetAttributeValue(session, dataObject, [ { type: pkcs11js.CKA_LABEL }, { type: pkcs11js.CKA_VALUE }, { type: pkcs11js.CKA_TOKEN } ]); console.log("Label:", attrs[0].value.toString()); console.log("Value:", attrs[1].value.toString()); // Find objects by template pkcs11.C_FindObjectsInit(session, [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_DATA } ]); let handle = pkcs11.C_FindObjects(session); while (handle) { const objAttrs = pkcs11.C_GetAttributeValue(session, handle, [ { type: pkcs11js.CKA_LABEL } ]); console.log("Found object:", objAttrs[0].value.toString()); handle = pkcs11.C_FindObjects(session); } pkcs11.C_FindObjectsFinal(session); // Copy object const copiedObject = pkcs11.C_CopyObject(session, dataObject, [ { type: pkcs11js.CKA_LABEL, value: "Copied object" } ]); // Get object size const size = pkcs11.C_GetObjectSize(session, dataObject); console.log("Object size:", size, "bytes"); // Destroy objects pkcs11.C_DestroyObject(session, copiedObject); pkcs11.C_DestroyObject(session, dataObject); } finally { pkcs11.C_Logout(session); pkcs11.C_CloseSession(session); pkcs11.C_Finalize(); } ``` -------------------------------- ### Initialize NSS with PKCS#11 Source: https://context7.com/peculiarventures/pkcs11js/llms.txt Initializes the Mozilla NSS library as a PKCS#11 provider with custom configuration parameters. Ensure the NSS softokn3 library is accessible. ```javascript const pkcs11js = require("pkcs11js"); const pkcs11 = new pkcs11js.PKCS11(); // Load NSS softokn3 library pkcs11.load("/usr/local/opt/nss/lib/libsoftokn3.dylib"); // Initialize with NSS-specific parameters pkcs11.C_Initialize({ libraryParameters: "configdir='' certPrefix='' keyPrefix='' secmod='' flags=readOnly,noCertDB,noModDB,forceOpen,optimizeSpace", }); try { const info = pkcs11.C_GetInfo(); console.log("NSS Library:", info.libraryDescription); console.log("Version:", info.libraryVersion.major + "." + info.libraryVersion.minor); const slots = pkcs11.C_GetSlotList(true); console.log("Available slots:", slots.length); } finally { pkcs11.C_Finalize(); } ``` -------------------------------- ### Initialize NSS Crypto Library Source: https://github.com/peculiarventures/pkcs11js/blob/master/README.md Defines the interface for initialization options and demonstrates loading the NSS library. ```typescript interface InitializationOptions { /** * NSS library parameters */ libraryParameters?: string; /** * bit flags specifying options for `C_Initialize` * - CKF_LIBRARY_CANT_CREATE_OS_THREADS. True if application threads which are executing calls to the library * may not use native operating system calls to spawn new threads; false if they may * - CKF_OS_LOCKING_OK. True if the library can use the native operation system threading model for locking; * false otherwise */ flags?: number; } /** * Initializes the Cryptoki library * @param options Initialization options * Supports implementation of standard `CK_C_INITIALIZE_ARGS` and extended NSS format. * - if `options` is null or empty, it calls native `C_Initialize` with `NULL` * - if `options` doesn't have `libraryParameters`, it uses `CK_C_INITIALIZE_ARGS` structure * - if `options` has `libraryParameters`, it uses extended NSS structure */ C_Initialize(options?: InitializationOptions): void; ``` ```javascript const mod = new pkcs11.PKCS11(); mod.load("/usr/local/opt/nss/lib/libsoftokn3.dylib"); mod.C_Initialize({ libraryParameters: "configdir='' certPrefix='' keyPrefix='' secmod='' flags=readOnly,noCertDB,noModDB,forceOpen,optimizeSpace", }); // Your code here mod.C_Finalize(); ``` -------------------------------- ### Generate AES Symmetric Keys Source: https://context7.com/peculiarventures/pkcs11js/llms.txt Demonstrates creating 256-bit AES keys using both synchronous and asynchronous methods within a PKCS#11 session. ```javascript const pkcs11js = require("pkcs11js"); const pkcs11 = new pkcs11js.PKCS11(); pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); pkcs11.C_Initialize(); const slots = pkcs11.C_GetSlotList(true); const session = pkcs11.C_OpenSession(slots[0], pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION); pkcs11.C_Login(session, pkcs11js.CKU_USER, "12345"); try { // Generate 256-bit AES key (synchronous) const aesKey = pkcs11.C_GenerateKey(session, { mechanism: pkcs11js.CKM_AES_KEY_GEN }, [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_SECRET_KEY }, { type: pkcs11js.CKA_TOKEN, value: false }, { type: pkcs11js.CKA_LABEL, value: "My AES Key" }, { type: pkcs11js.CKA_VALUE_LEN, value: 256 / 8 }, { type: pkcs11js.CKA_ENCRYPT, value: true }, { type: pkcs11js.CKA_DECRYPT, value: true }, ]); console.log("AES Key Handle:", aesKey.toString("hex")); // Generate key asynchronously with Promise const aesKeyAsync = await pkcs11.C_GenerateKeyAsync(session, { mechanism: pkcs11js.CKM_AES_KEY_GEN }, [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_SECRET_KEY }, { type: pkcs11js.CKA_VALUE_LEN, value: 16 }, { type: pkcs11js.CKA_ENCRYPT, value: true }, { type: pkcs11js.CKA_DECRYPT, value: true }, ]); console.log("Async AES Key:", aesKeyAsync.toString("hex")); } finally { pkcs11.C_Logout(session); pkcs11.C_CloseSession(session); pkcs11.C_Finalize(); } ``` -------------------------------- ### RSA Signing and Verification Source: https://context7.com/peculiarventures/pkcs11js/llms.txt Shows how to sign and verify data using RSA keys, covering both single-part and multi-part operations. ```javascript const pkcs11js = require("pkcs11js"); const pkcs11 = new pkcs11js.PKCS11(); pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); pkcs11.C_Initialize(); const slots = pkcs11.C_GetSlotList(true); const session = pkcs11.C_OpenSession(slots[0], pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION); pkcs11.C_Login(session, pkcs11js.CKU_USER, "12345"); try { // Generate RSA key pair for signing const rsaKeys = pkcs11.C_GenerateKeyPair( session, { mechanism: pkcs11js.CKM_RSA_PKCS_KEY_PAIR_GEN }, [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PUBLIC_KEY }, { type: pkcs11js.CKA_MODULUS_BITS, value: 2048 }, { type: pkcs11js.CKA_PUBLIC_EXPONENT, value: Buffer.from([1, 0, 1]) }, { type: pkcs11js.CKA_VERIFY, value: true }, ], [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PRIVATE_KEY }, { type: pkcs11js.CKA_SIGN, value: true }, ] ); const data = Buffer.from("Message to sign"); // Single-part signing with SHA256-RSA-PKCS pkcs11.C_SignInit(session, { mechanism: pkcs11js.CKM_SHA256_RSA_PKCS }, rsaKeys.privateKey); const signature = pkcs11.C_Sign(session, data, Buffer.alloc(512)); console.log("Signature length:", signature.length); // Verify signature pkcs11.C_VerifyInit(session, { mechanism: pkcs11js.CKM_SHA256_RSA_PKCS }, rsaKeys.publicKey); const isValid = pkcs11.C_Verify(session, data, signature); console.log("Signature valid:", isValid); // Output: Signature valid: true // Multi-part signing pkcs11.C_SignInit(session, { mechanism: pkcs11js.CKM_SHA256_RSA_PKCS }, rsaKeys.privateKey); pkcs11.C_SignUpdate(session, Buffer.from("Part 1 of message")); pkcs11.C_SignUpdate(session, Buffer.from("Part 2 of message")); const multiPartSignature = pkcs11.C_SignFinal(session, Buffer.alloc(512)); // Multi-part verification pkcs11.C_VerifyInit(session, { mechanism: pkcs11js.CKM_SHA256_RSA_PKCS }, rsaKeys.publicKey); pkcs11.C_VerifyUpdate(session, Buffer.from("Part 1 of message")); pkcs11.C_VerifyUpdate(session, Buffer.from("Part 2 of message")); const multiPartValid = pkcs11.C_VerifyFinal(session, multiPartSignature); console.log("Multi-part signature valid:", multiPartValid); } finally { pkcs11.C_Logout(session); pkcs11.C_CloseSession(session); pkcs11.C_Finalize(); } ``` -------------------------------- ### Manage Sessions and Authenticate Users with PKCS11js Source: https://context7.com/peculiarventures/pkcs11js/llms.txt Open and manage sessions with cryptographic tokens, including user authentication and session lifecycle management. Ensure the PKCS11 instance is initialized and a slot is selected. ```javascript const pkcs11js = require("pkcs11js"); const pkcs11 = new pkcs11js.PKCS11(); pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); pkcs11.C_Initialize(); try { const slots = pkcs11.C_GetSlotList(true); const slot = slots[0]; // Open a read/write session const session = pkcs11.C_OpenSession(slot, pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION); // Get session info const sessionInfo = pkcs11.C_GetSessionInfo(session); console.log("Session State:", sessionInfo.state); console.log("Session Flags:", sessionInfo.flags); // Login as user (CKU_USER = 1) pkcs11.C_Login(session, pkcs11js.CKU_USER, "12345"); console.log("User logged in successfully"); // Perform cryptographic operations here... // Logout and close session pkcs11.C_Logout(session); pkcs11.C_CloseSession(session); // Or close all sessions: pkcs11.C_CloseAllSessions(slot); } finally { pkcs11.C_Finalize(); } ``` -------------------------------- ### RSA-OAEP Encryption and Decryption Source: https://context7.com/peculiarventures/pkcs11js/llms.txt Demonstrates generating an RSA key pair and performing encryption and decryption using the OAEP padding mechanism. ```javascript const pkcs11js = require("pkcs11js"); const pkcs11 = new pkcs11js.PKCS11(); pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); pkcs11.C_Initialize(); const slots = pkcs11.C_GetSlotList(true); const session = pkcs11.C_OpenSession(slots[0], pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION); pkcs11.C_Login(session, pkcs11js.CKU_USER, "12345"); try { // Generate RSA key pair for encryption const rsaKeys = pkcs11.C_GenerateKeyPair( session, { mechanism: pkcs11js.CKM_RSA_PKCS_KEY_PAIR_GEN }, [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PUBLIC_KEY }, { type: pkcs11js.CKA_MODULUS_BITS, value: 2048 }, { type: pkcs11js.CKA_PUBLIC_EXPONENT, value: Buffer.from([1, 0, 1]) }, { type: pkcs11js.CKA_ENCRYPT, value: true }, ], [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PRIVATE_KEY }, { type: pkcs11js.CKA_DECRYPT, value: true }, ] ); const oaepMechanism = { mechanism: pkcs11js.CKM_RSA_PKCS_OAEP, parameter: { type: pkcs11js.CK_PARAMS_RSA_OAEP, hashAlg: pkcs11js.CKM_SHA_1, mgf: pkcs11js.CKG_MGF1_SHA1, source: 1, sourceData: null, } }; const data = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6]); // Encrypt with public key pkcs11.C_EncryptInit(session, oaepMechanism, rsaKeys.publicKey); const encrypted = pkcs11.C_Encrypt(session, data, Buffer.alloc(4096)); console.log("RSA-OAEP Encrypted length:", encrypted.length); // Decrypt with private key pkcs11.C_DecryptInit(session, oaepMechanism, rsaKeys.privateKey); const decrypted = pkcs11.C_Decrypt(session, encrypted, Buffer.alloc(1024)); console.log("Decrypted matches:", data.equals(decrypted)); // Output: Decrypted matches: true } finally { pkcs11.C_Logout(session); pkcs11.C_CloseSession(session); pkcs11.C_Finalize(); } ``` -------------------------------- ### Generate RSA Key Pairs Source: https://context7.com/peculiarventures/pkcs11js/llms.txt Shows how to generate a 2048-bit RSA key pair by providing separate templates for the public and private keys. ```javascript const pkcs11js = require("pkcs11js"); const pkcs11 = new pkcs11js.PKCS11(); pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); pkcs11.C_Initialize(); const slots = pkcs11.C_GetSlotList(true); const session = pkcs11.C_OpenSession(slots[0], pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION); pkcs11.C_Login(session, pkcs11js.CKU_USER, "12345"); try { // Generate 2048-bit RSA key pair const rsaKeys = pkcs11.C_GenerateKeyPair( session, { mechanism: pkcs11js.CKM_RSA_PKCS_KEY_PAIR_GEN }, // Public key template [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PUBLIC_KEY }, { type: pkcs11js.CKA_TOKEN, value: false }, { type: pkcs11js.CKA_LABEL, value: "My RSA Public Key" }, { type: pkcs11js.CKA_PUBLIC_EXPONENT, value: Buffer.from([1, 0, 1]) }, { type: pkcs11js.CKA_MODULUS_BITS, value: 2048 }, { type: pkcs11js.CKA_ENCRYPT, value: true }, { type: pkcs11js.CKA_VERIFY, value: true }, ], // Private key template [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PRIVATE_KEY }, { type: pkcs11js.CKA_TOKEN, value: false }, { type: pkcs11js.CKA_LABEL, value: "My RSA Private Key" }, { type: pkcs11js.CKA_DECRYPT, value: true }, { type: pkcs11js.CKA_SIGN, value: true }, ] ); console.log("Public Key:", rsaKeys.publicKey.toString("hex")); console.log("Private Key:", rsaKeys.privateKey.toString("hex")); } finally { pkcs11.C_Logout(session); pkcs11.C_CloseSession(session); pkcs11.C_Finalize(); } ``` -------------------------------- ### Generate RSA Key Pair Source: https://github.com/peculiarventures/pkcs11js/blob/master/README.md This snippet demonstrates generating an RSA key pair using the CKM_RSA_PKCS_KEY_PAIR_GEN mechanism. It defines separate templates for the public and private keys, specifying attributes like class, token association, label, public exponent, modulus bits, and usage flags (verify for public, sign for private). ```javascript var publicKeyTemplate = [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PUBLIC_KEY }, { type: pkcs11js.CKA_TOKEN, value: false }, { type: pkcs11js.CKA_LABEL, value: "My RSA Public Key" }, { type: pkcs11js.CKA_PUBLIC_EXPONENT, value: new Buffer([1, 0, 1]) }, { type: pkcs11js.CKA_MODULUS_BITS, value: 2048 }, { type: pkcs11js.CKA_VERIFY, value: true } ]; var privateKeyTemplate = [ { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PRIVATE_KEY }, { type: pkcs11js.CKA_TOKEN, value: false }, { type: pkcs11js.CKA_LABEL, value: "My RSA Private Key" }, { type: pkcs11js.CKA_SIGN, value: true }, ]; var keys = pkcs11.C_GenerateKeyPair(session, { mechanism: pkcs11js.CKM_RSA_PKCS_KEY_PAIR_GEN }, publicKeyTemplate, privateKeyTemplate); ``` -------------------------------- ### Detect a Slot Event Source: https://github.com/peculiarventures/pkcs11js/blob/master/README.md Uses C_WaitForSlotEvent to monitor for hardware slot changes. Requires a Cryptoki version 2.01 or later. ```javascript var pkcs11js = require("pkcs11js"); var pkcs11 = new pkcs11js.PKCS11(); // Need a compliant Cryptoki Version 2.01 or later pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); pkcs11.C_Initialize(); try { const slotId = pkcs11.C_WaitForSlotEvent(pkcs11js.CKF_DONT_BLOCK); if (slotId) { console.log(`Slot ${slotId} has been inserted`); } else { console.log(`No slot event`); } } catch (e) { console.error(e); } finally { pkcs11.C_Finalize(); } ``` -------------------------------- ### Detect PKCS#11 Slot Events Source: https://context7.com/peculiarventures/pkcs11js/llms.txt Monitors for token insertion and removal events using a non-blocking call. Requires PKCS#11 library initialization. ```javascript const pkcs11js = require("pkcs11js"); const pkcs11 = new pkcs11js.PKCS11(); pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); pkcs11.C_Initialize(); try { // Non-blocking check for slot events const slotId = pkcs11.C_WaitForSlotEvent(pkcs11js.CKF_DONT_BLOCK); if (slotId) { console.log("Slot event detected on slot:", slotId.toString("hex")); const slotInfo = pkcs11.C_GetSlotInfo(slotId); console.log("Slot description:", slotInfo.slotDescription); } else { console.log("No slot event pending"); } // Note: Without CKF_DONT_BLOCK, this call would block until an event occurs // const blockingSlotId = pkcs11.C_WaitForSlotEvent(0); // Blocking call } finally { pkcs11.C_Finalize(); } ``` -------------------------------- ### Verify Data with RSA-PKCS Source: https://github.com/peculiarventures/pkcs11js/blob/master/README.md Verifies a signature against the original data using the RSA-PKCS mechanism and a specified public key. The verification process mirrors the signing process with updates. ```javascript pkcs11.C_VerifyInit(session, { mechanism: pkcs11js.CKM_SHA256_RSA_PKCS }, keys.publicKey); pkcs11.C_VerifyUpdate(session, new Buffer("Incoming message 1")); pkcs11.C_VerifyUpdate(session, new Buffer("Incoming message N")); var verify = pkcs11.C_VerifyFinal(session, signature); ``` -------------------------------- ### Encrypt Data with AES-CBC Source: https://github.com/peculiarventures/pkcs11js/blob/master/README.md Encrypts data using the AES-CBC mechanism. Requires initialization with a secret key and a random parameter (e.g., IV). Data can be encrypted in chunks. ```javascript var cbc_param = pkcs11.C_GenerateRandom(new Buffer(16)); pkcs11.C_EncryptInit( session, { mechanism: pkcs11js.CKM_AES_CBC, parameter: cbc_param }, secretKey ); var enc = new Buffer(0); enc = Buffer.concat([enc, pkcs11.C_EncryptUpdate(session, new Buffer("Incoming data 1"), new Buffer(16))]); enc = Buffer.concat([enc, pkcs11.C_EncryptUpdate(session, new Buffer("Incoming data N"), new Buffer(16))]); enc = Buffer.concat([enc, pkcs11.C_EncryptFinal(session, new Buffer(16))]); console.log(enc.toString("hex")); ``` -------------------------------- ### Generate Random Bytes with PKCS#11 Source: https://context7.com/peculiarventures/pkcs11js/llms.txt Generates cryptographically secure random bytes using the token's hardware RNG. Ensure the PKCS#11 library is loaded and initialized, and a session is open. ```javascript const pkcs11js = require("pkcs11js"); const pkcs11 = new pkcs11js.PKCS11(); pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so"); pkcs11.C_Initialize(); const slots = pkcs11.C_GetSlotList(true); const session = pkcs11.C_OpenSession(slots[0], pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION); try { // Generate random bytes const randomBytes = pkcs11.C_GenerateRandom(session, Buffer.alloc(32)); console.log("Random bytes:", randomBytes.toString("hex")); // Pre-allocated buffer approach const buffer = Buffer.alloc(20); pkcs11.C_GenerateRandom(session, buffer); console.log("Random (20 bytes):", buffer.toString("hex")); // Seed the random number generator with additional entropy const seedData = Buffer.from("additional entropy from external source"); pkcs11.C_SeedRandom(session, seedData); console.log("RNG seeded with additional entropy"); } finally { pkcs11.C_CloseSession(session); pkcs11.C_Finalize(); } ``` -------------------------------- ### Sign Data with RSA-PKCS Source: https://github.com/peculiarventures/pkcs11js/blob/master/README.md Signs data using the RSA-PKCS mechanism with a specified private key. The signing process can involve multiple updates before finalization. ```javascript pkcs11.C_SignInit(session, { mechanism: pkcs11js.CKM_SHA256_RSA_PKCS }, keys.privateKey); pkcs11.C_SignUpdate(session, new Buffer("Incoming message 1")); pkcs11.C_SignUpdate(session, new Buffer("Incoming message N")); var signature = pkcs11.C_SignFinal(session, Buffer(256)); ```