## Introduction

Storing and encrypting data at Google's scale requires using a central
cryptographic key management service with multiple layers of keys for the
encrypted data. An example of multiple layer of keys is *envelope encryption*,
which is the process of encrypting a key with another key.

You can encrypt data at both the *application layer* , which is responsible for
displaying data to users, and the *storage layer*, which provides the physical
storage of data.

By default, at the storage layer, Google Cloud [encrypts
customer content stored at rest](https://docs.cloud.google.com/docs/security/encryption/default-encryption) using envelope encryption, with Google's
internal key management service as the central keystore. If you're storing and
encrypting data yourself, you can use Cloud Key Management Service as your central
keystore at the application layer, which is the focus of this topic.

Cloud KMS stores keys in a *key hierarchy* designed for ease, with
access to resources in the key hierarchy governed by [Identity and Access Management](https://docs.cloud.google.com/kms/docs/iam.md.txt).
The following shows the main levels of a Cloud KMS key hierarchy:

![Resources](https://docs.cloud.google.com/static/kms/images/resources2.png)

Find out more about the key hierarchy at [object hierarchy](https://docs.cloud.google.com/kms/docs/object-hierarchy).

### Data encryption keys

The key used to encrypt data itself is called a *data encryption key* (DEK).

Here are best practices for managing DEKs:

- Generate DEKs locally.
- When stored, always ensure DEKs are encrypted at rest.
- For easy access, store the DEK near the data that it encrypts.
- Generate a new DEK every time you write the data. This means you don't need to rotate the DEKs.
- Do not use the same DEK to encrypt data from two different users.
- Use a strong algorithm such as 256-bit Advanced Encryption Standard (AES) in Galois Counter Mode (GCM).

### Key encryption keys

The DEK is encrypted (also known as *wrapped* ) by a *key encryption key* (KEK).
The process of encrypting a key with another key is known as *envelope
encryption*.

Here are best practices for managing KEKs:

- Store KEKs centrally.

- Set the granularity of the DEKs they encrypt based on their use case. For
  example, consider a workload that requires multiple DEKs to encrypt the
  workload's data chunks. You could use a single KEK to wrap all DEKs that
  are responsible for that workload's encryption.

- Rotate keys regularly, and also after a suspected incident. To learn more, see
  [key rotation](https://docs.cloud.google.com/kms/docs/key-rotation.md.txt).

## Balancing DEKs and KEKs

Having a smaller number of KEKs than DEKs and using a central key management
service makes storing and encrypting data at scale more manageable. A central
key service also is a singular point to more easily audit and restrict data
access.

Depending on your situation, and the volume of data you are encrypting, you may
choose to use a similar model. A single KEK can be used to protect many DEKs;
this model permits individual data objects to each have their own DEK without
massively increasing the volume of keys stored in a central key management
service.

Cloud Key Management Service was designed to manage KEKs, and thus the maximum data input
size for `Encrypt` and `Decrypt` functions is 64 KiB. However, for data that you
know will not approach that limit, you could use Cloud KMS to
encrypt and decrypt data directly.

## How to encrypt data using envelope encryption

The process of encrypting data is to generate a DEK locally, encrypt data with
the DEK, use a KEK to wrap the DEK, and then store the encrypted data and the
wrapped DEK. The KEK never leaves Cloud KMS.

![Encryption flow](https://docs.cloud.google.com/static/kms/images/envelope_encryption_store.svg)

To encrypt data using envelope encryption:

1. Generate a DEK locally. You could do this with an open source library such as
   [OpenSSL](https://www.openssl.org), specifying a cipher type and a password from which to generate the
   key. You can also specify a salt and digest to use, if desired.

2. Use this DEK locally to encrypt your data.

   As an example, you could use OpenSSL as shown in the [encrypting the
   message](https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption#Encrypting_the_message) example. For best practice, use 256-bit Advanced Encryption
   Standard (AES-256) cipher in Galois Counter Mode (GCM).
3. Generate a new key in Cloud KMS, or use an existing key, which
   will act as the KEK. Use this key to encrypt (wrap) the DEK.

4. Store the encrypted data and the wrapped DEK.

> [!WARNING]
> **Warning:** Do **NOT** store a plaintext DEK.

## How to decrypt data using envelope encryption

The process of decrypting data is to retrieve the encrypted data and the wrapped
DEK, identify the KEK that wrapped the DEK, use the KEK to unwrap the DEK, and
then use the unwrapped DEK to decrypt the data. The KEK never leaves
Cloud KMS.

![Decryption flow](https://docs.cloud.google.com/static/kms/images/envelope_encryption_retrieve.svg)

To decrypt data using envelope encryption:

1. Retrieve the encrypted data and the wrapped DEK.

2. Use the key stored in Cloud KMS to unwrap the encrypted DEK.

3. Use the plaintext DEK to decrypt the encrypted data. If using OpenSSL as
   earlier, see the [decrypting the message](https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption#Decrypting_the_Message) example.

For sample code that shows how to encrypt and decrypt with envelope
encryption, see [Client-side encryption with Tink and Cloud KMS](https://docs.cloud.google.com/kms/docs/client-side-encryption.md.txt).

## Integration with Google Cloud services

Several Google Cloud products are integrated with Cloud KMS
to support Customer-Managed Encryption Key (CMEK) functionality. CMEK with
Cloud KMS adds an extra layer of protection for your data, provides
you with control of your encryption keys, and leverages the key management
benefits of Cloud KMS. See [Using Cloud KMS with other
services](https://docs.cloud.google.com/kms/docs/using-other-products) to see a full list of products that support CMEK.

## Other options for Google Cloud services

For data stored in Google Cloud products that do not support CMEK, you
can implement your own application-layer encryption. This requires implementing
your own envelope encryption as described above, so that you store data
encrypted locally in Google Cloud. This is also how you could use
Cloud KMS to encrypt data you store in other cloud service
providers or on premises.

In addition to supporting CMEK, the following products support
Customer-Supplied Encryption Key (CSEK) functionality.

| Product | CSEK topic |
|---|---|
| Cloud Storage | [Customer-supplied encryption keys](https://docs.cloud.google.com/storage/docs/encryption/customer-supplied-keys.md.txt) |
| Compute Engine | [Encrypt disks with customer-supplied encryption keys](https://docs.cloud.google.com/compute/docs/disks/customer-supplied-encryption.md.txt) |

With CSEK, you supply your own AES-256 key to serve as the KEK, and your key
protects the DEKs that protect your data. Your CSEK key is protected by an
additional layer of protection, using a Cloud KMS key.

Now that you can
[import keys into Cloud KMS](https://docs.cloud.google.com/kms/docs/importing-a-key.md.txt), you can
import your keys and use them with CMEK-enabled services instead of relying on
CSEK.