Self-Defending KMS provides multiple interfaces to application developers. For C/C++ programmers, Self-Defending KMS provides a PKCS#11 interface through a library. For Java programmers, Self-Defending KMS can be accessed through the JCE interface and through Java SDK. Self-Defending KMS can also be accessed through its RESTful interface, documented at https://www.fortanix.com/api/
We provide examples for using Self-Defending KMS in 7 languages – a C++ program using the PKCS#11 interface, a Java program using the JCE interface, and other programs using the REST interface through Java, Python, Go, C#, PHP and Javascript SDKs
The example programs can be downloaded in full at the Downloads page.
C++
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);
}
C#
public void decrypt() {
EncryptionAndDecryptionApi encryptionAndDecryptionApi = new EncryptionAndDecryptionApi();
DecryptRequest decReq = new DecryptRequest(Alg: ObjectType.AES, Mode: CryptMode.CBC, Cipher: cipher, Iv: encResp.Iv);
DecryptResponse decResp = encryptionAndDecryptionApi.Decrypt(key.Kid, decReq);
}
Go
alg := sdkms.AlgorithmAes
decryptResponse, err := client.Decrypt(ctx, sdkms.DecryptRequest{
Key: sdkms.SobjectByID(*sobject.Kid),
Alg: &alg,
Mode: sdkms.CryptModeSymmetric(sdkms.CipherModeCbc),
Cipher: encryptResponse.Cipher,
Iv: encryptResponse.Iv,
})
if err != nil {
log.Fatalf("Failed to decrypt: %v", err)
}
fmt.Printf("Plaintext: %v\n", string(decryptResponse.Plain))
Java
private static DecryptResponse decrypt() {
DecryptRequest decryptRequest = new DecryptRequest()
.alg(ObjectType.AES)
.mode(CryptMode.CBC)
.cipher(encryptResponse.getCipher())
.iv(encryptResponse.getIv());
EncryptionAndDecryptionApi encryptionAndDecryptionApi =
new EncryptionAndDecryptionApi(apiClient)
try {
DecryptResponse decryptResponse =
encryptionAndDecryptionApi.decrypt(kid, decryptRequest)
return decryptResponse;
} catch (Exception e) {
System.out.println("Decryption failed: " + e);
return null;
}
}
Python
def decrypt():
api_instance = sdkms.v1.EncryptionAndDecryptionApi(api_client=client)
decryption_request =
sdkms.v1.DecryptRequest( alg=ObjectType.AES,
mode=CipherMode.CBC,
cipher=encryption_response.cipher,
iv=encryption_response.iv)
try:
decryption_response = api_instance.decrypt(kid, decryption_request)
except ApiException as e:
print 'Exception when calling EncryptionAndDecryptionApi->decrypt: %s\n' % e)
PHP
public function decrypt() {
$decryptionRequestBody = array('alg' => $objType::AES, 'mode' => $cryptMode::CBC, 'cipher' => $encRes['cipher'], 'iv' => $encRes['iv']);
$decryptionRequest = new Swagger\Client\Model\DecryptRequest($decryptionRequestBody);
$encryptionAndDecryptionApi = new Swagger\Client\Api\EncryptionAndDecryptionApi($client);
$decryptionResponse = $encryptionAndDecryptionApi->decrypt($securityObjectResponse["kid"], $decryptionRequest); }
Javascript
var decryptCallback = function(error, data, response) {
if (error) {
console.error("Error: " + JSON.stringify(response));
} else {
console.log('Cipher decrypted successfully. result: ' + JSON.stringify(data));
}
};
var encryptionAndDecryptionApi = new FortanixSdkmsRestApi.EncryptionAndDecryptionApi()
var decryptRequest = FortanixSdkmsRestApi.DecrypttRequest.constructFromObject({"alg": "AES", "mode": "CBC", "cipher": "cipher"})
encryptionAndDecryptionApi.decrypt(data["kid"], decryptRequest, decryptCallback)