Encrypting application data

This topic shows one way to use Cloud Key Management Service to directly encrypt application data on a client, before transmitting it across a network.

In this example, the encrypted data is transmitted to Google Cloud and is stored in a Cloud Storage bucket. Cloud Storage also supports automatic server-side encryption using customer-managed encryption keys, which automates this entire process. To protect application data before transmitting it to Google Cloud, we recommend that you use the Tink library.

The Tink library is a multi-language, cross-platform library that provides simple and misuse-proof APIs for common cryptographic tasks. This can be used to encrypt data before it enters Google Cloud data stores, and supports Java, Python, C++, Go, Objective-C, and other languages, and both object storage and relational database services.

In this walk-through, you encrypt a file using Cloud KMS before you upload it to a bucket. Next, you download and decrypt the same data so that you can read it on the client.

When you follow these instructions, your keys and all cryptographic operations remain in Google Cloud and you need to use Cloud KMS for decryption. Raw symmetric encryption lets you encrypt or decrypt data locally on-premises or move encrypted data between different libraries and service providers without having to decrypt it first.

Before you begin

Within your Google Cloud organization, you need permission to create new projects, and to enable billing, create users, and manage permissions within these projects. The roles/resourcemanager.organizationAdmin role grants this permission.

Setup

We recommend using two projects and two users to ensure separation of duties. If you follow the steps in this topic, users and services that manage encryption keys are distinct from users and services that use them. One project contains and manages the keys, and the other project stores the encrypted data in a Cloud Storage bucket, and decrypts it as needed.

Create projects

You create projects in the Google Cloud console. For step-by-step instructions, see the Identity and Access Management quickstart.

Within the organization:

  1. Create a Google Cloud project to contain the Cloud Storage bucket used to store the secrets. The secrets will be stored as objects in the bucket. In the steps below, this project is referred to as my-storage-project.

  2. Optionally, create a second Google Cloud project to manage the Cloud KMS keys used to encrypt and decrypt the secret. In the steps below, this project is called my-kms-project.

    You can choose to use the same Google Cloud project for both my-storage-project and my-kms-project.

  3. For each project, enable the Cloud KMS API and enable billing, by following the steps in the Before you begin section of the Cloud KMS Quickstart.

Create users

You create users and grant them roles in the Google Cloud console. For step-by-step instructions, see the Identity and Access Management quickstart.

This procedure creates two users. key-admin manages the encryption keys, and key-user can encrypt and decrypt data using the keys.

Perform this procedure in the my-kms-project project.

  1. Create the key-admin user. To create users, you need the roles/resourcemanager.organizationAdmin role for the my-kms-project project.

  2. Grant key-admin the roles/cloudkms.admin Identity and Access Management role. key-admin can create and manage keys.

  3. Create the key-user user.

  4. Grant key-user the roles/cloudkms.cryptoKeyEncrypterDecrypter IAM role. key-user can use keys to encrypt and decrypt data.

Create a storage bucket

Perform this procedure in the my-storage-project project.

  1. Create a storage bucket called my-bucket.
  2. Grant key-user the roles/storage.objectAdmin role for the my-bucket storage bucket.

Create an encryption key

Perform this procedure as the key-admin user in the my-kms-project project.

  1. Create a key ring called storage. The name of a key ring is unique to the project. A key ring cannot be renamed or deleted. Use the Google Cloud CLI to create a key ring.

    gcloud kms keyrings create storage \
      --location global
    
  2. Create a key named my-key in the storage key ring, for the purpose of encryption. The name of a key is unique to the key ring. A key cannot be renamed or deleted, but its key versions can be destroyed. Use the Google Cloud CLI to create the key. An initial key version is created automatically and becomes the primary version.

    gcloud kms keys create my-key \
     --location global \
     --keyring storage \
     --purpose encryption
    

You can learn more about Creating key rings and keys.

Encrypt the file that contains the secret

Perform this procedure as the key-user user, using both projects.

  1. On your local machine, create a file called my-secret.txt, which contains the text "This is my secret."

    echo "This is my secret" > my-secret.txt
    
  2. Encrypt my-secret.txt using the my-key key in the my-kms-project project. Write the encrypted file to mysecret.txt.encrypted.

    gcloud kms encrypt \
     --location global \
     --keyring storage \
     --key my-key \
     --plaintext-file my-secret.txt \
     --ciphertext-file my-secret.txt.encrypted
    

    You can learn more about encrypting data by following the encrypt data quickstart.

    Use raw-encrypt instead for raw symmetric encryption.

  3. Upload the encrypted my-secret.txt.encrypted file to the my-bucket storage bucket in the my-storage-project project. You can use the gsutil command.

    gsutil cp my-secret.txt.encrypted gs://my-storage-bucket
    

    You can learn more about uploading objects to a storage bucket.

  4. [Optional] Delete the plaintext my-secret.txt file from the local machine. This is a good practice for files containing unencrypted sensitive data.

The my-storage-bucket storage bucket now contains the file my-secret.txt.encrypted, which is encrypted using the my-key key,

Decrypt the file that contains the secret

Perform these steps as the key-user user, using both projects.

  1. Download the my-secret.txt.encrypted file from the my-bucket storage bucket. You can use the gsutil command.

    gsutil cp gs://my-storage-bucket/my-secret.txt.encrypted .
    

    You can learn more about downloading objects from a storage bucket.

  2. Try to read the file using a command like less or a text editor. Notice that it is not a plain-text file.

  3. Decrypt the my-secret.txt.encrypted and save the decrypted data to a new plaintext file called my-secret.txt.decrypted, using the same key that you used to encrypt my-secret.txt.

    gcloud kms decrypt --location global \
     --keyring storage \
     --key my-key \
     --ciphertext-file my-secret.txt.encrypted \
     --plaintext-file my-secret.txt.decrypted
    

    You can learn more about decrypting data by following the encrypt data quickstart.

    Use raw-decrypt instead for raw symmetric encryption.

  4. Read the my-secret.txt.decrypted file using the cat command. Its contents are identical to the original contents of my-secret.txt.

    cat my-secret.txt.decrypted
    
    This is my secret.
  5. [Optional] Delete the my-secret.txt.encrypted and my-secret.txt.decrypted files from the local machine.

Cleaning up

To clean up, delete all the files you created on the local machine, then delete the [MY_KMS_PROJECT] and [MY_STORAGE_PROJECT] projects.

What's next