Now, we have the master key and we can generate data key to start the data encryption process. It can be achieved in 2 ways. 1) Using KMS API in the application. 2) Using KMS command line tool.
Inside the application, to start data encryption/decryption, we will first need to get the master key. As you already know, this key is stored in the AWS account only, and the application keeps solely data keys. It is assumed, that AWS API itself is already configured with correct credentials. So we will focus on interesting API methods for our case only. If you’re interested to know how to install AWS API you can read the description there.
All the code snippets will be provided using PHP language.
To work with AWS KMS service, we will need Aws\Kms\KmsClient class :
$kmsClient = new KmsClient([
‘version’ => ‘latest’,
‘region’ => ‘us-east-2’,
‘credentials’ => $credentials // <— for your account.
Now, let’s get our previously created master key :
$keySpec = ‘AES_256’;
$masterKeyId = ‘cd6b1a3e-e8c0-4366-bab8-e141975ca2b3’;
$dataKey = $kmsClient->generateDataKey([
‘KeyId’ => $masterKeyId,
‘KeySpec’ => $keySpec,
As you can see, to generate a data key, we need to know only the master key’s ID and the algorithm to crypt. As a result, this method returns an object which holds 2 representation of a data key. The first one is encrypted, the second one is in the plaintext format. Why so? Because inside an application, we should store only encrypted key. But all the operation with data will be performed using a plaintext key. After all the operations are done, the plaintext key should be removed.
To get an encrypted data key, you need to get a CiphertextBlob key from response object :
To get a plaintext data key, you need to get a Plaintext key from response object :
So, now we have generated the data key, and can start the data encryption process. For this part, AWS API is no longer needed. We can use native PHP means.
// prepare key.
$cipher = “AES-128-CBC”;
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
$key = base64_encode($dataKey[‘Plaintext’]); // <— Plaintext data key.
// encrypt the data.
$ciphertext = openssl_encrypt($text, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
// decrypt the data.
$original_plaintext = openssl_decrypt($ciphertext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
In the sample above, both encryption and decryption processes go together. But in reality, the flow will be different. Following the encryption, the plaintext data key will be deleted, and the encrypted data key will most likely be stored in the database. Then, when data will be decrypted back, and the encrypted data key will be extracted from database end decrypted to plaintext format.
$ciphertextBlobDataKey; // <— get encrypted value from database.
$result = $kmsClient->decrypt([
‘CiphertextBlob’ => $ciphertextBlobDataKey,
$plaintextKey = $result[‘Plaintext’];
That is all you need to do basic data encoding / decoding. Of course, KMS API provides much more actions to manipulate the data. You can find all of it there.
KMS command line
Another way of using AWS KMS service is executing console commands either manually or by application. To do so, you need to install AWS Encryption CLI SDK first, and you can find how to do it there.
Once it is installed, you have everything you need to perform encryption / decryption processes. As an example, to encrypt “hello.txt” file, you can execute command below :
\\ To run this example, replace the fictitious CMK ARN with a valid value.
$ aws-encryption-cli –encrypt \
–input hello.txt \
–master-keys key=$cmkArn \
–metadata-output ~/metadata \
–encryption-context purpose=test \
To understand the basics with more examples, please see this documentation page.
AWS KMS service allows you to bring data protection topic for your application on the next level. If an application keeps some sensitive information in the database or any other storages, potentially it can be stolen. Thus, keeping the data in a plain format or an insufficient level of encryption, potentially provides a way to still it and decrypt. Especially, if encryption keys are stored along with the data. With AWS KMS service you can encrypt everything including encryption keys itself. And keep your master key out of an application.
An additional level of protection can be achieved by using AWS KMS service with conjunction with AWS SecretManager service which can keep all the credentials you have in secured place and in secured form. For example, you can move all the passwords from configuration files to AWS SM service and load it in an application at runtime.
Such a conjunction allows to achieve proper security and data protection. No sensitive information like passwords is present neither in files nor database. All the sensitive data is encrypted including encryption key. Only you need is to properly protect AWS API credentials on the server.
Regarding pricing, AWS KMS includes 20 000 free requests per month and 1 USD for each master key. AWS SM is free during the first month of use. Then, it costs 0,05 USD for 10 000 API calls and 0,40 USD for a single confidential point of information.