Updated: May 17, 2017

SmartKey provides multiple interfaces to application developers. For C/C++ programmers, SmartKey provides a PKCS#11 interface through a library. For Java programmers, SmartKey can be accessed through the JCE interface. SmartKey can also be accessed through its RESTful interface, documented at

We provide examples for using SmartKey in 3 languages – a C++ program using the PKCS#11 interface, a Java program using the JCE interface, and a Python program using the REST interface.

Download the code to initialize and login. The example programs can be downloaded in full at

string decrypt(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey, string iv_cipher) {
    CK_RV rv;
    CK_BYTE *plain;
    CK_ULONG plain_len;
    string iv;
    string cipher;

    Base64::Decode(iv_cipher.substr(0, iv_cipher.find(':')), &iv);
    CK_MECHANISM mechanism = {
      CKM_AES_CBC_PAD, (CK_BYTE_PTR) iv.c_str(), iv.length()

    rv = p11->C_DecryptInit(hSession, &mechanism, hKey);
    if (rv == CKR_OK) {
	      Base64::Decode(iv_cipher.substr(iv_cipher.find(':')+1, iv_cipher.length() - iv_cipher.find(':') + 1), &cipher);
        rv = p11->C_Decrypt(hSession, (CK_BYTE_PTR) cipher.c_str(), cipher.length(), NULL, &plain_len);
        if (rv == CKR_OK) {
			      plain = (CK_BYTE *)malloc(plain_len * sizeof(CK_BYTE));
            rv = p11->C_Decrypt(hSession, (CK_BYTE_PTR) cipher.c_str(), cipher.length(), plain, &plain_len);
    if (rv != CKR_OK) {
        cout << "Decryption failed. Error code = " << rv << endl;
				return string();
    return string((char*)plain, plain_len);

private static String decrypt(Provider provider, SecretKey key, String cipherStruct, String mode) {
    try {
        String[] ivAndCipherText = cipherStruct.split(":");
        byte[] iv = new Base64().decode(ivAndCipherText[0]);
        byte[] cipherText = new Base64().decode(ivAndCipherText[1]);
        Cipher cipher = Cipher.getInstance(mode, provider);
        cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
        byte[] bytePlainText = cipher.doFinal(cipherText);

        return new String(bytePlainText);
    } catch (Exception e) {
        System.out.println("Decryption failed: " + e);
        return null;

def decrypt(bearer_token, kid, iv_cipher, type, mode):
    iv, cipher = iv_cipher.split(':')
    decrypt_request = {'cipher': cipher, 'alg': type, 'mode': mode, 'iv': iv}
    res = requests.request(method='POST',
                           url="" + kid + "/decrypt",
                           headers={'Authorization' : 'Bearer ' + bearer_token},
    if res.status_code !=
        print "Can't decrypt: " + str(res.status_code)
        return None
        return base64.b64decode(res.json()['plain'])