Symmetric Cryptography

Updated: August 9, 2017

SmartKey can perform encryption and decryption of data with symmetric ciphers. See the SmartKey developer’s guide for information on supported cryptosystems and block cipher modes.

Prerequisites

Performing symmetric cryptography requires an SmartKey account, a group with a symmetric key, and an application configured in that group. See the SmartKey Developer’s Guide for more details.

Required Operations

The symmetric key must have the Encrypt operation enabled for encryption and the Decrypt operation enabled for decryption. In addition, the key must be enabled.

Authorization and Configuration

You must first authenticate and optionally configure a default API client as described in Configure API Client and Client Authentication. Performing cryptography requires authenticating as an app with an API key or a client certificate. (User accounts cannot perform encryption and decryption).

Create an EncryptionAndDecryptionApi Client Object

Encryption is performed using an EncryptionAndDecryptionApi object.

import com.fortanix.sdkms.v1.api.EncryptionAndDeryptionApi();

EncryptionAndDecryptionApi cryptoApi = new EncryptionAndDecryptionApi();

Encrypting Data

Create an Encryption Request

The encryption request object encodes the request parameters. The plain (plaintext), alg (symmetric algorithm) and mode (block encryption mode) parameters are required. The plaintext should be binary data passed as an array of bytes. alg must match the type of the key being used to perform encryption. The tag_len parameter is required for GCM and CCM cipher modes and ignored for other cipher modes. The iv and ad parameters are optional or ignored depending on the mode. See below for more details.

import com.fortanix.sdkms.v1.model.CipherMode;
import com.fortanix.sdkms.v1.model.ObjectType;
import com.fortanix.sdkms.v1.model.EncryptRequest;

EncryptRequest encryptRequest = new encryptRequest().plain(<plaintext data as byte[]>).alg(ObjectType.<AES, DES or DES3>).mode(CipherMode.<some cipher mode>);

iv (Initialization Vector, or Nonce)

An initialization vector (or nonce) is used with all block cipher modes except for ECB. SmartKey will automatically generate a random IV if you do not supply one in the encryption request. Since block ciphers can be broken if an IV is reused, it is strongly recommended that you allow SmartKey to create initialization vector. You will typically only supply your own IV only if you need to interoperate with other systems that require IVs to be selected in a particular way. If you choose to generate your own IVs, it is your responsibility to understand the cryptographic considerations and ensure that your generation strategy is appropriate.

tag_len

For authenticating cipher modes GCM and CCM, the tag_len parameter is required. This parameter specifies the length (in bits) of the authentication tag produced by the cipher that is used to authenticate the ciphertext when decrypting.

ad (Authenticated Data)

For authenticating cipher modes GCM and CCM, additional authenticated data may be provided. Authenticated data is not included in the plaintext (so will not be encrypted), but will be integrity checked when decrypting. This field is optional and does not need to be set if you have no additional authenticated data to provide.

Make the Encryption Call

Data is encryped with the encrypt() method of the EncryptionAndDecryptionApi object. encrypt() is called with the UUID of the key used to perform encryption, and the encryption request. The UUID of the key can be found in the key details page of the UI, or it can be retrieved by looking up keys with the API.

import com.fortanix.sdkms.v1.model.EncryptResponse;

EncryptResponse encryptResponse = cryptoApi.encrypt(<key UUID>, encryptRequest);
byte[] ciphertext = encryptResponse.getCipher();

IV and Tag in the Response

The IV (for modes other than ECB) and authentication tag (for GCM and CCM mode) are supplied in the response. You will need to save these along with the ciphertext in order to later decrypt.

byte[] iv = encryptResponse.getIv();
byte[] tag = encryptResponse.getTag(); // for GCM and CCM only

Decrypting Data

In order to decrypt data, you will need the ciphertext and IV (for all modes except for ECB). For GCM or CCM mode, you will also need the (unencrypted) authenticated data provided during encryption (if any) and the authentication tag.

Create a Decryption Request

The decryption request object encodes the request parameters. The cipher (cipehrtext), alg (symmetric algorithm) and mode (block encryption mode) parameters are required. The iv paramter is required for all modes except for ECB. For GCM and CCM, the tag parameter is required, and ad is optional but must match the ad provided during encryption. The ciphertext should be binary data passed as an array of bytes. alg must match the type of key being used to perform encryption.

import com.fortanix.sdkms.v1.model.ObjectType;
import com.fortanix.sdkms.v1.model.DecryptRequest;

DecryptRequest decryptRequest = new decryptRequest()
        .cipher(<ciphertext data as byte[]>)
        .alg(ObjectType.RSA)
        .iv(<iv data as byte[]>);

// For GCM/CCM only:
decryptRequest.setAd(<ad data as byte[]>);
decryptRequest.setTag(<tag data as byte[]>);

Make the Decryption Call

Data is decrypted with the decrypt() method of the EncryptionAndDecryptionApi object. decrypt() is called with the UUID of the key used to perform decryption, and the decryption request. The UUID of the key can be found in the key details page of the UI, or it can be retried by looking up keys with the API.

import com.fortanix.sdkms.v1.model.DecryptResponse;

DecryptResponse decryptResponse = cryptoApi.decrypt(<key UUID>, decryptRequest);
byte[] plaintext = decryptResponse.getPlain();