Develop at PKCS#11 Level

Here you code at the Cryptoki level, using Java wrapper class for the CORE implementation of the PKCSClosedPublic-Key Cryptography Standards - Industry-standard cryptography specifications.#11 standard. This level allows you to use features that are not supported by the standard JCAClosedJava Cryptography Architecture - Java frameworks for implementing cryptography primitives. framework, e.g. creating keys with specific properties.

The CORE Client package provides Java wrapper for the Unbound PKCSClosedPublic-Key Cryptography Standards - Industry-standard cryptography specifications.#11 implementation, as specified in Unbound PKCS#11 Implementation.

  • The relevant packages is: com/dyadicsec/cryptoki
  • For the API list refer to Functions List.

Functions List

The wrapper API is included in the com.dyadicsec.cryptoki package. The main class, including all functionality, is the com.dyadicsec.cryptoki.Library class, which provides the following methods. For additional information, refer to OASIS PKCS#11 specification.

Note
All methods throw a CKR_Exception.

  • C_CloseAllSessions - closes all sessions an application has with a token.

    static void C_CloseAllSessions(int slotID)

  • C_CloseSession - closes a session between an application and a token.

    static void C_CloseSession(CK_SESSION_HANDLE hSession)

  • C_CreateObject - creates a new object.

    static int C_CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE[] pTemplate)

  • C_Decrypt - decrypts encrypted data in a single part.

    static byte[] C_Decrypt(CK_SESSION_HANDLE hSession, byte[] pEncryptedData)

  • C_Decrypt - decrypts encrypted data in a single part.

    static int C_Decrypt(CK_SESSION_HANDLE hSession, byte[] pEncryptedData, int inOffset, int inLen, byte[] out, int outOffset)

  • C_DecryptFinal - finishes a multiple-part decryption operation.

    static byte[] C_DecryptFinal(CK_SESSION_HANDLE hSession)

  • C_DecryptFinal - finishes a multiple-part decryption operation.

    static int C_DecryptFinal(CK_SESSION_HANDLE hSession, byte[] out, int offset)

  • C_DecryptInit - initializes a decryption operation.

    static void C_DecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM pMechanism, int hKey)

  • C_DecryptUpdate - continues a multiple-part decryption operation, processing another encrypted data part.

    static byte[] C_DecryptUpdate(CK_SESSION_HANDLE hSession, byte[] pEncryptedPart)

  • C_DecryptUpdate - continues a multiple-part decryption operation, processing another encrypted data part.

    static int C_DecryptUpdate(CK_SESSION_HANDLE hSession, byte[] pEncryptedPart, int inOffset, int inLen, byte[] out, int outOffset)

  • C_DeriveKey - derives a key from a base key, creating a new key object.

    static int C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM pMechanism, int hBaseKey, CK_ATTRIBUTE[] pTemplate)

  • C_DestroyObject - destroys an object.

    static void C_DestroyObject(CK_SESSION_HANDLE hSession, int hObject)

  • C_Digest - digests data in a single part.

    static byte[] C_Digest(CK_SESSION_HANDLE hSession, byte[] data)

  • C_Digest - digests data in a single part.

    static int C_Digest(CK_SESSION_HANDLE hSession, byte[] data, int inOffset, int inLen, byte[] out, int outOffset)

  • C_DigestFinal - finishes a multiple-part message-digesting operation, returning the message digest.

    static byte[] C_DigestFinal(CK_SESSION_HANDLE hSession)

  • C_DigestFinal - finishes a multiple-part message-digesting operation, returning the message digest.

    static int C_DigestFinal(CK_SESSION_HANDLE hSession, byte[] out, int offset)

  • C_DigestInit - initializes a message-digesting operation.

    static void C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM pMechanism)

  • C_DigestKey - digests a key.

    static void C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)

  • C_DigestUpdate - continues a multiple-part message-digesting operation, processing another data part.

    static void C_DigestUpdate(CK_SESSION_HANDLE hSession, byte[] pPart)

  • C_DigestUpdate - continues a multiple-part message-digesting operation, processing another data part.

    static void C_DigestUpdate(CK_SESSION_HANDLE hSession, byte[] pPart, int offset, int len)

  • C_Encrypt - encrypts single-part data.

    static byte[] C_Encrypt(CK_SESSION_HANDLE hSession, byte[] pData)

  • C_Encrypt - encrypts single-part data.

    static int C_Encrypt(CK_SESSION_HANDLE hSession, byte[] pData, int inOffset, int inLen, byte[] out, int outOffset)

  • C_EncryptFinal - finishes a multiple-part encryption operation.

    static byte[] C_EncryptFinal(CK_SESSION_HANDLE hSession)

  • C_EncryptFinal - finishes a multiple-part encryption operation.

    static int C_EncryptFinal(CK_SESSION_HANDLE hSession, byte[] out, int offset)

  • C_EncryptInit - initializes an encryption operation.

    static void C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM pMechanism, int hKey)

  • C_EncryptUpdate - continues a multiple-part encryption operation, processing another data part.

    static byte[] C_EncryptUpdate(CK_SESSION_HANDLE hSession, byte[] pPart)

  • C_EncryptUpdate - continues a multiple-part encryption operation, processing another data part.

    static int C_EncryptUpdate(CK_SESSION_HANDLE hSession, byte[] pPart, int inOffset, int inLen, byte[] out, int outOffset)

  • C_Finalize - is called to indicate that an application is finished with the Cryptoki library.

    static void C_Finalize()

  • C_FindObjects - continues a search for token and session objects that match a template, obtaining additional object handles.

    static int[] C_FindObjects(CK_SESSION_HANDLE hSession, int ulMaxObjectCount)

  • C_FindObjectsFinal - terminates a search for token and session objects.

    static void C_FindObjectsFinal(CK_SESSION_HANDLE hSession)

  • C_FindObjectsInit - initializes a search for token and session objects that match a template.

    static void C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE[] pTemplate)

  • C_GenerateKey - generates a secret key or set of domain parameters, creating a new object.

    static int C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM pMechanism, CK_ATTRIBUTE[] pTemplate)

  • C_GenerateKeyPair - generates a public/private key pair, creating new key objects.

    static int[] C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM pMechanism, CK_ATTRIBUTE[] pPublicKeyTemplate, CK_ATTRIBUTE[] pPrivateKeyTemplate)

  • C_GenerateRandom - generates random or pseudo-random data.

    static void C_GenerateRandom(CK_SESSION_HANDLE hSession, byte[] randomData, int offset, int len)

  • C_GenerateRandom - generates random or pseudo-random data.

    static byte[] C_GenerateRandom(CK_SESSION_HANDLE hSession, int len)

  • C_GetAttributeValue - obtains the value of one or more attributes of an object.

    static void C_GetAttributeValue(CK_SESSION_HANDLE hSession, int hObject, CK_ATTRIBUTE[] pTemplate)

  • C_GetInfo - returns general information about Cryptoki.

    static CK_INFO C_GetInfo()

  • C_GetMechanismInfo - obtains information about a particular mechanism possibly supported by a token.

    static CK_MECHANISM_INFO C_GetMechanismInfo(int slotID, int type)

  • C_GetMechanismList - is used to obtain a list of mechanism types supported by a token.

    static int[] C_GetMechanismList(int slotID)

  • C_GetSessionInfo - obtains information about a session.

    static CK_SESSION_INFO C_GetSessionInfo(CK_SESSION_HANDLE hSession)

  • C_GetSlotInfo - obtains information about a particular slot in the system.

    static CK_SLOT_INFO C_GetSlotInfo(int slotID)

  • C_GetSlotList - is used to obtain a list of slots in the system.

    static int[] C_GetSlotList(boolean tokenPresent)

  • C_GetTokenInfo - obtains information about a particular token in the system. 

    static CK_TOKEN_INFO C_GetTokenInfo(int slotID)

  • C_Initialize - initializes the Cryptoki library.

    static void C_Initialize()

  • C_Login - logs a user into a token. 

    static void C_Login(CK_SESSION_HANDLE hSession, int userType, char[] pPin)

  • C_Logout - logs a user out from a token.

    static void C_Logout(CK_SESSION_HANDLE hSession)

  • C_OpenSession - opens a session between an application and a token in a particular slot.

    static CK_SESSION_HANDLE C_OpenSession(int slotID, int flags)

  • C_SeedRandom - mixes additional seed material into the token’s random number generator.

    static void C_SeedRandom(CK_SESSION_HANDLE hSession, byte[] pSeed)

  • C_SeedRandom - mixes additional seed material into the token’s random number generator.

    static void C_SeedRandom(CK_SESSION_HANDLE hSession, byte[] pSeed, int offset, int len)

  • C_SetAttributeValue - modifies the value of one or more attributes of an object.

    static void C_SetAttributeValue(CK_SESSION_HANDLE hSession, int hObject, CK_ATTRIBUTE[] pTemplate)

  • C_Sign - signs data in a single part, where the signature is an appendix to the data.

    static byte[] C_Sign(CK_SESSION_HANDLE hSession, byte[] pData)

  • C_Sign - signs data in a single part, where the signature is an appendix to the data.

    static int C_Sign(CK_SESSION_HANDLE hSession, byte[] pData, int inOffset, int inLen, byte[] out, int outOffset)

  • C_SignFinal - finishes a multiple-part signature operation, returning the signature.

    static byte[] C_SignFinal(CK_SESSION_HANDLE hSession)

  • C_SignFinal - finishes a multiple-part signature operation, returning the signature.

    static int C_SignFinal(CK_SESSION_HANDLE hSession, byte[] out, int offset)

  • C_SignInit - initializes a signature operation, where the signature is an appendix to the data.

    static void C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM pMechanism, int hKey)

  • C_SignUpdate - continues a multiple-part signature operation, processing another data part.

    static void C_SignUpdate(CK_SESSION_HANDLE hSession, byte[] pPart)

  • C_SignUpdate - continues a multiple-part signature operation, processing another data part.

    static void C_SignUpdate(CK_SESSION_HANDLE hSession, byte[] pPart, int offset, int len)

  • C_UnwrapKey - unwraps (i.e. decrypts) a wrapped key, creating a new private key or secret key object.

    static int C_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM pMechanism, int hUnwrappingKey, byte[] pWrappedKey, CK_ATTRIBUTE[] pTemplate)

  • C_UnwrapKey - unwraps (i.e. decrypts) a wrapped key, creating a new private key or secret key object.

    static int C_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM pMechanism, int hUnwrappingKey, byte[] pWrappedKey, int offset, int len, CK_ATTRIBUTE[] pTemplate)

  • C_Verify - verifies a signature in a single-part operation, where the signature is an appendix to the data.

    static void C_Verify(CK_SESSION_HANDLE hSession, byte[] pData, byte[] pSignature)

  • C_Verify - verifies a signature in a single-part operation, where the signature is an appendix to the data.

    static void C_Verify(CK_SESSION_HANDLE hSession, byte[] pData, int inOffset, int inLen, byte[] pSignature, int sigOffset, int sigLen)

  • C_VerifyFinal - finishes a multiple-part verification operation, checking the signature.

    static void C_VerifyFinal(CK_SESSION_HANDLE hSession, byte[] pSignature)

  • C_VerifyFinal - finishes a multiple-part verification operation, checking the signature.

    static void C_VerifyFinal(CK_SESSION_HANDLE hSession, byte[] pSignature, int offset, int len)

  • C_VerifyInit - initializes a verification operation, where the signature is an appendix to the data.

    static void C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM pMechanism, int hKey)

  • C_VerifyUpdate - continues a multiple-part verification operation, processing another data part.

    static void C_VerifyUpdate(CK_SESSION_HANDLE hSession, byte[] pPart)

  • C_VerifyUpdate - continues a multiple-part verification operation, processing another data part.

    static void C_VerifyUpdate(CK_SESSION_HANDLE hSession, byte[] pPart, int offset, int len)

  • C_WrapKey - wraps (i.e. encrypts) a private or secret key.

    static byte[] C_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM pMechanism, int hWrappingKey, int hKey)

  • C_WrapKey - wraps (i.e. encrypts) a private or secret key.

    static int C_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM pMechanism, int hWrappingKey, int hKey, byte[] out, int offset)

Error Codes

A description of the error codes can be found in the PKCS11 specification. The following table lists the possible errors with links to the error description in the specification.

Error Code Name
0x00000000 CKR_OK
0x00000001 CKR_CANCEL
0x00000002 CKR_HOST_MEMORY
0x00000003 CKR_SLOT_ID_INVALID
0x00000005 CKR_GENERAL_ERROR
0x00000006 CKR_FUNCTION_FAILED
0x00000007 CKR_ARGUMENTS_BAD
0x00000008 CKR_NO_EVENT
0x00000009 CKR_NEED_TO_CREATE_THREADS
0x0000000A CKR_CANT_LOCK
0x00000010 CKR_ATTRIBUTE_READ_ONLY
0x00000011 CKR_ATTRIBUTE_SENSITIVE
0x00000012 CKR_ATTRIBUTE_TYPE_INVALID
0x00000013 CKR_ATTRIBUTE_VALUE_INVALID
0x00000020 CKR_DATA_INVALID
0x00000021 CKR_DATA_LEN_RANGE
0x00000030 CKR_DEVICE_ERROR
0x00000031 CKR_DEVICE_MEMORY
0x00000032 CKR_DEVICE_REMOVED
0x00000040 CKR_ENCRYPTED_DATA_INVALID
0x00000041 CKR_ENCRYPTED_DATA_LEN_RANGE
0x00000050 CKR_FUNCTION_CANCELED
0x00000051 CKR_FUNCTION_NOT_PARALLEL
0x00000054 CKR_FUNCTION_NOT_SUPPORTED
0x00000060 CKR_KEY_HANDLE_INVALID
0x00000062 CKR_KEY_SIZE_RANGE
0x00000063 CKR_KEY_TYPE_INCONSISTENT
0x00000064 CKR_KEY_NOT_NEEDED
0x00000065 CKR_KEY_CHANGED
0x00000066 CKR_KEY_NEEDED
0x00000067 CKR_KEY_INDIGESTIBLE
0x00000068 CKR_KEY_FUNCTION_NOT_PERMITTED
0x00000069 CKR_KEY_NOT_WRAPPABLE
0x0000006A CKR_KEY_UNEXTRACTABLE
0x00000070 CKR_MECHANISM_INVALID
0x00000071 CKR_MECHANISM_PARAM_INVALID
0x00000082 CKR_OBJECT_HANDLE_INVALID
0x00000090 CKR_OPERATION_ACTIVE
0x00000091 CKR_OPERATION_NOT_INITIALIZED
0x000000A0 CKR_PIN_INCORRECT
0x000000A1 CKR_PIN_INVALID
0x000000A2 CKR_PIN_LEN_RANGE
0x000000A3 CKR_PIN_EXPIRED
0x000000A4 CKR_PIN_LOCKED
0x000000B0 CKR_SESSION_CLOSED
0x000000B1 CKR_SESSION_COUNT
0x000000B3 CKR_SESSION_HANDLE_INVALID
0x000000B4 CKR_SESSION_PARALLEL_NOT_SUPPORTED
0x000000B5 CKR_SESSION_READ_ONLY
0x000000B6 CKR_SESSION_EXISTS
0x000000B7 CKR_SESSION_READ_ONLY_EXISTS
0x000000B8 CKR_SESSION_READ_WRITE_SO_EXISTS
0x000000C0 CKR_SIGNATURE_INVALID
0x000000C1 CKR_SIGNATURE_LEN_RANGE
0x000000D0 CKR_TEMPLATE_INCOMPLETE
0x000000D1 CKR_TEMPLATE_INCONSISTENT
0x000000E0 CKR_TOKEN_NOT_PRESENT
0x000000E1 CKR_TOKEN_NOT_RECOGNIZED
0x000000E2 CKR_TOKEN_WRITE_PROTECTED
0x000000F0 CKR_UNWRAPPING_KEY_HANDLE_INVALID
0x000000F1 CKR_UNWRAPPING_KEY_SIZE_RANGE
0x000000F2 CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT
0x00000100 CKR_USER_ALREADY_LOGGED_IN
0x00000101 CKR_USER_NOT_LOGGED_IN
0x00000102 CKR_USER_PIN_NOT_INITIALIZED
0x00000103 CKR_USER_TYPE_INVALID
0x00000104 CKR_USER_ANOTHER_ALREADY_LOGGED_IN
0x00000105 CKR_USER_TOO_MANY_TYPES
0x00000110 CKR_WRAPPED_KEY_INVALID
0x00000112 CKR_WRAPPED_KEY_LEN_RANGE
0x00000113 CKR_WRAPPING_KEY_HANDLE_INVALID
0x00000114 CKR_WRAPPING_KEY_SIZE_RANGE
0x00000115 CKR_WRAPPING_KEY_TYPE_INCONSISTENT
0x00000120 CKR_RANDOM_SEED_NOT_SUPPORTED
0x00000121 CKR_RANDOM_NO_RNG
0x00000130 CKR_DOMAIN_PARAMS_INVALID
0x00000150 CKR_BUFFER_TOO_SMALL
0x00000160 CKR_SAVED_STATE_INVALID
0x00000170 CKR_INFORMATION_SENSITIVE
0x00000180 CKR_STATE_UNSAVEABLE
0x00000190 CKR_CRYPTOKI_NOT_INITIALIZED
0x00000191 CKR_CRYPTOKI_ALREADY_INITIALIZED
0x000001A0 CKR_MUTEX_BAD
0x000001A1 CKR_MUTEX_NOT_LOCKED
0x80000000 CKR_VENDOR_DEFINED

Code Samples

The following sample code contains examples of the PKCSClosedPublic-Key Cryptography Standards - Industry-standard cryptography specifications.#11 wrapper in Java.

Open a Session

CK_SESSION_HANDLE hSession = Library.C_OpenSession(slotID, CK.CKF_RW_SESSION| CK.CKF_SERIAL_SESSION);

Generate RSA Key Pair

int[] rsaKeyHandles = Library.C_GenerateKeyPair(hSession, new CK_MECHANISM(CK.CKM_RSA_PKCS_KEY_PAIR_GEN),

// Public key template:
new CK_ATTRIBUTE[]
{
  new CK_ATTRIBUTE(CK.CKA_TOKEN, false),
  new CK_ATTRIBUTE(CK.CKA_CLASS, CK.CKO_PUBLIC_KEY),
  new CK_ATTRIBUTE(CK.CKA_KEY_TYPE, CK.CKK_RSA),
  new CK_ATTRIBUTE(CK.CKA_MODULUS_BITS, 2048),
},

// Private key template:
new CK_ATTRIBUTE[]
{
  new CK_ATTRIBUTE(CK.CKA_TOKEN, true),
  new CK_ATTRIBUTE(CK.CKA_CLASS, CK.CKO_PRIVATE_KEY),
  new CK_ATTRIBUTE(CK.CKA_KEY_TYPE, CK.CKK_RSA),
});

int rsaPubKeyHandle = rsaKeyHandles[0];
int rsaPrvKeyHandle = rsaKeyHandles[1];

Extract Public Key

CK_ATTRIBUTE[] rsaPubKeyMaterial = new CK_ATTRIBUTE[]
{
  new CK_ATTRIBUTE(CK.CKA_MODULUS),
  new CK_ATTRIBUTE(CK.CKA_PUBLIC_EXPONENT)
};

Library.C_GetAttributeValue(hSession, rsaPubKeyHandle, rsaPubKeyMaterial);
BigInteger modulus =
(BigInteger)rsaPubKeyMaterial[0].pValue;
BigInteger publicExponent =
(BigInteger)rsaPubKeyMaterial[1].pValue;

KeyFactory kf = KeyFactory.getInstance("RSA", "SunRsaSign");
RSAPublicKey rsaPubKey = (RSAPublicKey)kf.generatePublic(new RSAPublicKeySpec(modulus, publicExponent));

Generate AES key

keyHandle = Library.C_GenerateKey(hSession, new CK_MECHANISM(CK.CKM_AES_KEY_GEN), new CK_ATTRIBUTE[]
{
  new CK_ATTRIBUTE(CK.CKA_TOKEN, true),
  new CK_ATTRIBUTE(CK.CKA_CLASS, CK.CKO_SECRET_KEY),
  new CK_ATTRIBUTE(CK.CKA_KEY_TYPE, CK.CKK_AES),
  new CK_ATTRIBUTE(CK.CKA_VALUE_LEN, 32),
});

Wrap AES key

int srcKeyHandle = …
int wrapKeyHandle = …
byte[] iv = new byte[16];
SecureRandom.getInstanceStrong().nextBytes(iv);
byte[] wrappedKeyData = Library.C_WrapKey(hSession, new CK_MECHANISM(CK.CKM_AES_CBC, iv), wrapKeyHandle, srcKeyHandle);

Unwrap AES key

byte[] wrappedKeyData = …
int wrappedKeyHandle = …
int unwrappedKeyHandle = Library.C_UnwrapKey(hSession,
new CK_MECHANISM(CK.CKM_RSA_PKCS), wrappedKeyHandle, wrappedKeyData,
new CK_ATTRIBUTE[]
{
  new CK_ATTRIBUTE(CK.CKA_TOKEN, true),
  new CK_ATTRIBUTE(CK.CKA_CLASS, CK.CKO_SECRET_KEY),
  new CK_ATTRIBUTE(CK.CKA_KEY_TYPE, CK.CKK_AES),
});