# Configure encryption at rest

Aerospike Enterprise Edition (EE) can be configured to strongly encrypt data “at rest” - on storage devices (flash, memory, Intel Optane™ Persistent Memory) using NIST standards.

Encryption at rest involves a user-supplied encryption key, which can be rotated, and two server-generated random encryption keys. The server encryption keys are derived from the user-supplied encryption key. Without this user-supplied encryption key, the server’s data storage cannot be decrypted. If this key is lost, the data stored on the devices becomes inaccessible.

Encryption at rest requires the `asdb-encryption-at-rest` feature-key. See [Providing the Feature-Key File](https://aerospike.com/docs/database/8.1.0/manage/planning/feature-key).

### Data encryption key (DEK)

The data encryption key (DEK) is a [symmetric key](https://en.wikipedia.org/wiki/Symmetric-key_algorithm) used to both encrypt and decrypt data on a storage device. The [`encryption`](https://aerospike.com/docs/database/reference/config#namespace__encryption) configuration parameter defines whether to use `aes-128` or `aes-256` as the basis for the DEK.

To create a DEK, the server uses a cryptographically strong random number generator (OpenSSL’s `RAND_bytes()` function). The size of the DEK is 128 bits if [AES-128](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) is selected, or 256 bits if AES-256 is selected. Each storage device, in a namespace configured with encryption at rest, has a unique DEK. If the device is wiped, the server will generate a new DEK for it.

Aerospike encrypts each record with the XTS-AES block cipher mode (detailed in [IEEE P1619 standard for disk encryption](https://ieeexplore.ieee.org/document/4375278) and [NIST Special Publication (SP) 800-38E](https://csrc.nist.gov/publications/detail/sp/800-38e/final)), which respectively double the key size of the DEK to 256 bits or 512 bits.

### Key encryption key (KEK)

The key encryption key (KEK) encrypts and decrypt the device’s DEK. The KEK is derived from the user-supplied [`encryption-key-file`](https://aerospike.com/docs/database/reference/config#namespace__encryption-key-file), acting as the passphrase for the NIST-approved Password-Based Key Derivation Function 2 ([PBKDF2](https://en.wikipedia.org/wiki/PBKDF2)).

Aerospike reads the encrypted DEK from each device and decrypts it using the KEK. Aerospike tests whether the device’s DEK is valid by checking a “canary” or “verification” value stored in the device header. If the canary value is not decipherable, the process is retried with the user-supplied [`encryption-old-key-file`](https://aerospike.com/docs/database/reference/config#namespace__encryption-key-file). This allows for rotating the KEK.

## Configuring storage encryption

Encryption at rest is configured per namespace, using three configuration parameters

-   The user-defined [`encryption-key-file`](https://aerospike.com/docs/database/reference/config#namespace__encryption-key-file) turns on encryption at rest for the namespace.
-   [`encryption-old-key-file`](https://aerospike.com/docs/database/reference/config#namespace__encryption-old-key-file) is optional and used when rotating the KEK.
-   The optional [`encryption`](https://aerospike.com/docs/database/reference/config#namespace__encryption) parameter controls the strength of the server encryption keys.

These configuration parameters can be supplied through the file system, an environment variable, [fetched from HashiCorp Vault](https://aerospike.com/docs/database/8.1.0/manage/security/vault), or fetched from a secrets management service using [Aerospike Secret Agent](https://aerospike.com/docs/database/8.1.0/manage/security/secrets).

In the namespace [`storage-engine`](https://aerospike.com/docs/database/reference/config#namespace__storage-engine) configuration:

```text
namespace test {

    ...

    storage-engine device {

        device /dev/sda1

        ...

        encryption-key-file key.dat

        encryption-old-key-file prev-key.dat

        encryption aes-128

    }

    ...

}
```

### Generating a strong encryption key file

The contents of the user-specified `encryption-key-file`, like a password, must be unpredictable to an adversary. An adversary who knows the contents of the key file can decrypt your storage device. A large key file is not enough if it is predictable.

For this reason, we recommend an adequate number of random bytes from a reliable source of randomness - NIST recommends 128 bits for PBKDF2 uses. For example:

Terminal window

```bash
head --bytes 256 /dev/urandom > key.dat
```

You should use different keys for different namespaces. In all cases, your encryption key files must be kept private on an encrypted and secure operating system environment or fetched from a secrets management service.

## Managing storage encryption

### Enabling or disabling storage encryption

Enabling namespace storage encryption by setting `encryption-key-file` for the first time, disabling encryption by removing `encryption-key-file` from the namespace configuration, or changing the `encryption` algorithm, requires that you wipe the namespace storage.

This process must be completed one cluster node at a time:

1.  Quiesce the cluster node, then stop the Aerospike server process (`asd`). You should [delay “fill” migrations](https://aerospike.com/docs/database/8.1.0/manage/cluster/delay-migrations).
2.  Wipe the namespace storage by using `dd` or `blkdiscard` for devices, and `rm` for file-based storage.
3.  Modify the namespace configuration in `aerospike.conf`.
4.  Restart the Aerospike server process on the cluster node.

Repeat this process for all the cluster nodes.

::: note
Prior to Aerospike Database 5.7.0, this process was also necessary for rotating key encryption keys.
:::

### Rotating the KEK

To rotate the key encryption key, do the following one cluster node at a time:

1.  First, quiesce and shut down the Aerospike server process. You should [delay “fill” migrations](https://aerospike.com/docs/database/8.1.0/manage/cluster/delay-migrations).
2.  Modify the node’s `aerospike.conf` and set the _current_ user-defined `encryption-key-file` as the [`encryption-old-key-file`](https://aerospike.com/docs/database/reference/config#namespace__encryption-old-key-file).
3.  Provide a new, randomly generated [`encryption-key-file`](https://aerospike.com/docs/database/reference/config#namespace__encryption-key-file).
4.  Restart the Aerospike server process on the cluster node.

Once the node restarts successfully the new KEK will be saved, and the `encryption-old-key-file` configuration line should be removed. If you don’t, then you’ll see a warning whenever you restart `asd: ignoring invalid old encryption key`. The server will start up, and encryption will work, though.

## Performance

Disk encryption typically works on a per-sector basis. However, Aerospike optimizes disk encryption performance by encrypting each record separately. Records on disk are treated as variable-size disk sectors, up to 1MiB in size. Beyond 1MiB records are split into 1-MiB chunks.

The performance impact of storage encryption depends on the host hardware, as well as the average size of the records. A definitive answer regarding the performance impact can thus only be obtained by benchmarking on the deployed hardware with realistic data.

Certain CPUs, such as Intel Xeon chips, provide on-chip hardware acceleration. In one typical hardware configuration, we observed that records smaller than 512 bytes resulted in a 20% drop in TPS performance. Benchmarking 1KiB, 5KiB, and 10KiB record sizes **did not** lead to any measurable performance loss.