Encrypting and decrypting data with an asymmetric key

This topic provides information about creating and using a key for asymmetric encryption using an RSA key. If you want to use asymmetric keys for creating and validating signatures, see Creating and validating digital signatures. If you want to use symmetric keys for encryption and decryption, see Encrypting and decrypting data.

Asymmetric encryption uses the public key portion of the asymmetric key and decryption uses the private key portion of the key. Cloud Key Management Service provides functionality to retrieve the public key and functionality to decrypt ciphertext that was encrypted with the public key. Cloud KMS does not allow direct access to the private key.

Before you begin

  • This topic provides examples that run at the command line. To simplify using the examples, use Cloud Shell. The encryption example uses OpenSSL, which is pre-installed on Cloud Shell.

  • Create an asymmetric key with key purpose of ASYMMETRIC_DECRYPT. To see which algorithms are supported for key purpose ASYMMETRIC_DECRYPT, see Asymmetric encryption algorithms. You cannot follow this procedure with a key with purpose of ASYMMETRIC_SIGN.

  • If you are going to use the command line, install OpenSSL if you do not already have it. If you use Cloud Shell, OpenSSL is already installed.

  • macOS users: The version of OpenSSL installed on macOS does not support the flags used to decrypt data in this topic. To follow these steps on macOS, install OpenSSL from Homebrew.

Access control to the key

  • For a user or service that will retrieve the public key, grant the cloudkms.cryptoKeyVersions.viewPublicKey permission on the asymmetric key. The public key is required for encrypting data.

  • For a user or service that will decrypt data that was encrypted with the public key, grant the cloudkms.cryptoKeyVersions.useToDecrypt permission on the asymmetric key.

Learn about permissions and roles in Cloud KMS at Permissions and Roles.

Encrypt data

To encrypt data using an asymmetric encryption key, retrieve the public key and use the public key to encrypt the data.

gcloud

This sample requires OpenSSL to be installed on your local system.

Download public key

Download the public key:

gcloud kms keys versions get-public-key key-version \
    --key key \
    --keyring key-ring \
    --location location  \
    --output-file public-key-path

Replace key-version with the key version that has the public key. Replace key with the name of the key. Replace key-ring with the name of the key ring where the key is located. Replace location with the Cloud KMS location for the key ring. Replace public-key-path with the location to save the public key on the local system.

Encrypt data

Encrypt data using the public key you just downloaded and save the output to a file:

openssl pkeyutl -in cleartext-data-input-file \
    -encrypt \
    -pubin \
    -inkey public-key-path \
    -pkeyopt rsa_padding_mode:oaep \
    -pkeyopt rsa_oaep_md:sha256 \
    -pkeyopt rsa_mgf1_md:sha256 \
    > encrypted-data-output-file
  • Replace cleartext-data-input-file with the path and file name to encrypt.

  • Replace public-key-path with the path and file name where you downloaded the public key.

  • Replace encrypted-data-output-file with the path and file name to save the encrypted data.

C#

To run this code, first set up a C# development environment and install the Cloud KMS C# SDK.


using Google.Cloud.Kms.V1;
using System;
using System.Security.Cryptography;
using System.Text;

public class EncryptAsymmetricSample
{
    public byte[] EncryptAsymmetric(
      string projectId = "my-project", string locationId = "us-east1", string keyRingId = "my-key-ring", string keyId = "my-key", string keyVersionId = "123",
      string message = "Sample message")
    {
        // Create the client.
        KeyManagementServiceClient client = KeyManagementServiceClient.Create();

        // Build the key version name.
        CryptoKeyVersionName keyVersionName = new CryptoKeyVersionName(projectId, locationId, keyRingId, keyId, keyVersionId);

        // Get the public key.
        PublicKey publicKey = client.GetPublicKey