> ## Documentation Index
> Fetch the complete documentation index at: https://docs.futurex.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage keys and encrypt with C++

> Use the FXCL C++ API to create, retrieve, rotate, and delete a CryptoHub AES key store and perform client-side encryption and decryption.

Use a retrievable CryptoHub key store to obtain the active AES key and perform encryption inside the C++ application process.

## What you'll build

The example performs this lifecycle:

1. Create a retrievable AES-256 key store.
2. Retrieve the active key through `KeyStore`.
3. Encrypt and decrypt data locally with AES-CBC and PKCS #7 padding.
4. Rotate the active key.
5. Delete the test key store.

## Before you begin

Complete [Install and authenticate FXCL](./install-and-authenticate). The authenticated partition must permit key-store create, retrieve, rotate, and delete operations.

<Warning>
  AES-CBC provides confidentiality but not authenticated integrity. Protect the ciphertext with a separate integrity control, or use an approved authenticated construction that your application and Futurex product version support.
</Warning>

## Create a retrievable key store

```cpp theme={null}
#include <fxcl/KeyAlgo.h>
#include <fxcl/KeyUsage.h>
#include <fxcl/TimePeriod.h>
#include <fxcl/TimeUnit.h>
#include <fxcl/kmes/KeyStore.h>
#include <fxcl/kmes/KeyStoreInfo.h>
#include <fxcl/kmes/KeyStoreManager.h>

fxcl::kmes::KeyStoreManager manager(server);

fxcl::kmes::KeyStoreInfo info;
info.setName("customer-data-encryption");
info.setKeyAlgo(fxcl::KeyAlgo::AES);
info.setKeyBits(256);
info.setKeyUsage(
    fxcl::KeyUsage::Encrypt | fxcl::KeyUsage::Decrypt
);
info.setRetrievable(true);
info.setRotationPeriod(
    fxcl::TimePeriod(fxcl::TimeUnit::Day, 90)
);

fxcl::kmes::KeyStore store;
if (!manager.createStore(info, store) || !store.isValid()) {
    throw std::runtime_error(manager.getError().c_str());
}
```

`setRetrievable(true)` permits FXCL to return the active key for a client-side operation. The clear key can enter application memory.

You should receive a valid `KeyStore` with an active `SecretKey`.

## Encrypt and decrypt locally

```cpp theme={null}
#include <fxcl/BlockCipherMode.h>
#include <fxcl/ByteArray.h>
#include <fxcl/Decrypt.h>
#include <fxcl/Encrypt.h>
#include <fxcl/Padding.h>
#include <fxcl/SymCipherParams.h>

const fxcl::ByteArray plaintext("application data");
fxcl::ByteArray ciphertext;
fxcl::ByteArray recovered;

fxcl::SymCipherParams params;
params.setMode(fxcl::BlockCipherMode::CBC);
params.setPadding(fxcl::Padding::PKCS7);

fxcl::Encrypt encrypt;
encrypt.setKey(store.getKey());
encrypt.setParams(params);
if (!encrypt.encrypt(plaintext, ciphertext)) {
    throw std::runtime_error("FXCL encryption failed");
}

fxcl::Decrypt decrypt;
decrypt.setKey(store.getKey());
decrypt.setParams(params);
if (!decrypt.decrypt(ciphertext, recovered)) {
    throw std::runtime_error("FXCL decryption failed");
}

if (recovered != plaintext) {
    throw std::runtime_error("Decrypted data does not match");
}
```

Store the initialization vector and cipher parameters with the ciphertext. Decryption must use the same parameters and the key version that encrypted the data.

You should recover the original byte sequence exactly.

## Rotate the key store

```cpp theme={null}
if (!manager.rotateStore(store)) {
    throw std::runtime_error(manager.getError().c_str());
}
```

Rotation creates a new active key and expires the prior active key. Keep the key identifier or DPM header with existing ciphertext so the application can select the correct historical key for decryption.

## Delete a test key store

```cpp theme={null}
if (!manager.deleteStore("customer-data-encryption")) {
    throw std::runtime_error(manager.getError().c_str());
}
```

Deleting a key store can make its ciphertext unrecoverable. Delete only test-owned stores or stores that completed the approved retention and destruction process.

## Build the application

```bash theme={null}
g++ -std=c++17 -O2 -Wall -Wextra \
  -DFXCL_OSSL_3 app.cpp \
  -o app \
  -lfxcl -pthread
```

The `FXCL_OSSL_3` definition must match the installed OpenSSL 3 package.

## Verify it works

Use a dedicated test store and a known plaintext. Require all of these results:

* `createStore` returns a valid store.
* `getKey` returns the active AES key.
* The decrypt result exactly matches the input.
* `rotateStore` succeeds.
* `deleteStore` removes the test store.

Do not record the API key, active key, plaintext, ciphertext, or decrypted value in application logs.

## Troubleshooting

| Signal                              | Cause                                                                           | Action                                                                                   |
| ----------------------------------- | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| Key-store creation fails            | The identity lacks the key-store operation or the Host API command is disabled. | Verify the partition, Excrypt port, and `RKCS`, `RKCK`, and `RKES` command availability. |
| Local encryption cannot get a key   | The store is non-retrievable or has no active key.                              | Use a retrievable store for client-side encryption and confirm an active key exists.     |
| Decryption returns different data   | The key version, IV, mode, or padding does not match encryption.                | Persist and restore the full encryption context.                                         |
| Old ciphertext fails after rotation | The application selected only the new active key.                               | Retain the original key identifier or use a DPM header to select the historical key.     |

## Version and scope

This procedure was validated with FXCL 1.9.5, CryptoHub 7.2.0.7, Ubuntu 22.04, GCC 11, and the OpenSSL 3 FXCL package.


## Related topics

- [Test encryption and decryption with externally managed key](/Integrations/KMES_Series_3/Cloud_key_management/Google_Cloud_EKM_External_Key_Manager/Test_encryption_and_decryption_with_externally_managed_key.md)
- [Test encryption and decryption with the externally managed key](/Integrations/VirtuCrypt/Google_Cloud_EKM_External_Key_Manager/Test_encryption_and_decryption_with_the_externally_managed_key.md)
- [Gmail only: Upload encryption keys for client-side encryption](/Integrations/CryptoHub/Data_protection/Google_Workspace_CSE_for_Gmail/Gmail_only_Upload_encryption_keys_for_client-side_encryption.md)
- [Load major keys](/Integrations/HSM/Key_management/HashiCorp_Vault_-_Managed_Keys/Configure_the_Vectera_Plus/Load_major_keys.md)
- [Load Major Keys](/Integrations/HSM/Secrets_management/HashiCorp_Vault/Configure_the_Vectera_Plus/Load_Major_Keys.md)
