## Encrypt your data {#encrypting-your-data}
### Generate the encryption key {#generate-key-no-kms}
The following steps assume that you are not using KMS, and therefore the steps also
assume that you need to generate an encryption key. If you already have an encryption key,
skip to [Write an encryption configuration file](#write-an-encryption-configuration-file).
{{< caution >}}
Storing the raw encryption key in the EncryptionConfig only moderately improves your security posture,
compared to no encryption.
For additional secrecy, consider using the `kms` provider as this relies on keys held outside your
Kubernetes cluster. Implementations of `kms` can work with hardware security modules or with
encryption services managed by your cloud provider.
To learn about setting
up encryption at rest using KMS, see
[Using a KMS provider for data encryption](/docs/tasks/administer-cluster/kms-provider/).
The KMS provider plugin that you use may also come with additional specific documentation.
{{< /caution >}}
Start by generating a new encryption key, and then encode it using base64:
{{< tabs name="generate_encryption_key" >}}
{{% tab name="Linux" %}}
Generate a 32-byte random key and base64 encode it. You can use this command:
```shell
head -c 32 /dev/urandom | base64
```
You can use `/dev/hwrng` instead of `/dev/urandom` if you want to
use your PC's built-in hardware entropy source. Not all Linux
devices provide a hardware random generator.
{{% /tab %}}
{{% tab name="macOS" %}}
<!-- localization note: this is similar to the Linux tab and the wording
should match wherever the English text does -->
Generate a 32-byte random key and base64 encode it. You can use this command:
```shell
head -c 32 /dev/urandom | base64
```
{{% /tab %}}
{{% tab name="Windows" %}}
Generate a 32-byte random key and base64 encode it. You can use this command:
```powershell
# Do not run this in a session where you have set a random number
# generator seed.
[Convert]::ToBase64String((1..32|%{[byte](Get-Random -Max 256)}))
```
{{% /tab %}}
{{< /tabs >}}
{{< note >}}
Keep the encryption key confidential, including while you generate it and
ideally even after you are no longer actively using it.
{{< /note >}}
### Replicate the encryption key
Using a secure mechanism for file transfer, make a copy of that encryption key
available to every other control plane host.
At a minimum, use encryption in transit - for example, secure shell (SSH). For more
security, use asymmetric encryption between hosts, or change the approach you are using
so that you're relying on KMS encryption.
### Write an encryption configuration file
{{< caution >}}
The encryption configuration file may contain keys that can decrypt content in etcd.
If the configuration file contains any key material, you must properly
restrict permissions on all your control plane hosts so only the user
who runs the kube-apiserver can read this configuration.
{{< /caution >}}
Create a new encryption configuration file. The contents should be similar to:
```yaml
---
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
- configmaps
- pandas.awesome.bears.example
providers:
- aescbc:
keys:
- name: key1
# See the following text for more details about the secret value
secret: <BASE 64 ENCODED SECRET>
- identity: {} # this fallback allows reading unencrypted secrets;
# for example, during initial migration
```
To create a new encryption key (that does not use KMS), see
[Generate the encryption key](#generate-key-no-kms).
### Use the new encryption configuration file
You will need to mount the new encryption config file to the `kube-apiserver` static pod. Here is an example on how to do that:
1. Save the new encryption config file to `/etc/kubernetes/enc/enc.yaml` on the control-plane node.
1. Edit the manifest for the `kube-apiserver` static pod: `/etc/kubernetes/manifests/kube-apiserver.yaml` so that it is similar to: