Encryption

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 http://support.smartkey.io/api/index.html

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 http://support.smartkey.io/smartkey/resources.html


string encrypt(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey, string plain) {
    CK_RV rv;
    CK_BYTE *iv;
    CK_ULONG iv_len;
    string iv_b64;
    CK_BYTE *cipher;
    CK_ULONG cipher_len;
    string cipher_b64;

    iv_len = (CK_ULONG) AES_KEYLENGTH/8;
    iv = (CK_BYTE *)malloc(iv_len * sizeof(CK_BYTE));
    CK_MECHANISM mechanism = {
      CKM_AES_CBC_PAD, iv, iv_len
    };
    Base64::Encode(string((char *)iv, iv_len), &iv_b64);

    rv = p11->C_EncryptInit(hSession, &mechanism, hKey);
    if (rv == CKR_OK) {
        rv = p11->C_Encrypt(hSession, (CK_BYTE_PTR) plain.c_str(), plain.length(), NULL, &cipher_len);
        if (rv == CKR_OK) {
            cipher = (CK_BYTE *)malloc(cipher_len * sizeof(CK_BYTE));
            rv = p11->C_Encrypt(hSession, (CK_BYTE_PTR) plain.c_str(), plain.length(), cipher, &cipher_len);
        }
    }
    if (rv != CKR_OK) {
        cout << "Encryption failed. Error code = " << rv << endl;
        return string();
    }
    Base64::Encode(string((char *)cipher, cipher_len), &cipher_b64);
    return iv_b64 + ":" + cipher_b64;
}


private static String encrypt(Provider provider, SecretKey key, String plain, String mode, int length) {
    byte[] iv = new byte[length / 8];
    SecureRandom prng = new SecureRandom();
    prng.nextBytes(iv);

    try {
        Cipher cipher = Cipher.getInstance(mode, provider);
        cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
        byte[] byteCipherText = cipher.doFinal(plain.getBytes());
        String cryptStruct = new Base64().encodeAsString(iv) + ":" + new Base64().encodeAsString(byteCipherText);
        return cryptStruct;
    } catch (Exception e) {
        System.out.println("Encryption failed: " + e);
        return null;
    }
}


def encrypt(bearer_token, kid, plain, type, mode):
    iv = base64.b64encode(bytearray(random.sample(range(1,100),AES_KEYLENGTH/8)))
    encrypt_request = {'plain': base64.b64encode(plain), 'alg': type, 'mode': mode, 'iv': iv}
    res = requests.request(method='POST',
                           url="https://www.smartkey.io/crypto/v1/keys/" + kid + "/encrypt",
                           headers={'Authorization' : 'Bearer ' + bearer_token},
                           data=json.dumps(encrypt_request))
    if res.status_code != requests.codes.ok:
        print "Can't encrypt: " + str(res.status_code)
        return None
    else:
        return res.json()['iv'] + ':' + res.json()['cipher']