Re-encrypting data

This topic shows how to re-encrypt data. If you suspect unauthorized use of a key, you should re-encrypt the data protected by that key and then disable or schedule destruction of the prior CryptoKeyVersion.

Before you begin

This scenario requires the following conditions.

  • You have already encrypted data using Cloud KMS.

  • The CryptoKeyVersion used for the encryption is not disabled, scheduled for destruction, or destroyed. You use this CryptoKeyVersion to decrypt the encrypted data.

  • You have already rotated keys. A key rotation creates a new primary CryptoKeyversion. You use the new primary CryptoKeyVersion to re-encrypt the data.

Re-encrypting data workflow

Use the following steps to re-encrypt data and disable or schedule destruction of the CryptoKeyVersion used for the original encryption.

  1. Decrypt the data using the prior CryptoKeyVersion

  2. Re-encrypt the data using the new primary CryptoKeyVersion

  3. Disable or schedule destruction of the prior CryptoKeyVersion

Decrypt the data using the prior CryptoKeyVersion

Cloud KMS automatically uses the correct CryptoKeyVersion to decrypt data, as long as the CryptoKeyVersion is not disabled, scheduled for destruction, or destroyed. The following examples show how to decrypt the data. This is the same decryption code used in Encrypting and Decrypting.

Command-line

To decrypt data, provide the appropriate key information, specify the name of the encrypted file (ciphertext file) to decrypt, and specify the name of the file that will contain the decrypted content.

gcloud kms decrypt \
    --location=global \
    --keyring=my-key-ring \
    --key=my-key \
    --ciphertext-file=YOUR_FILEPATH_AND_FILENAME_TO_DECRYPT \
    --plaintext-file=YOUR_FILEPATH_AND_FILENAME_TO_DECRYPT.dec

The decrypt command supports an optional --additional-authenticated-data- file flag to specify a file that contains additional authenticated data. The additional authenticated data file must not be larger than 64 KiB.

If --ciphertext-file or --additional-authenticated-data-file is set to -, that file is read from stdin. Similarly, if --plaintext-file is set to -, the decrypted plaintext is written to stdout.

The following decrypt example shows how to specify additional authenticated data.

gcloud kms decrypt \
    --location=global \
    --keyring=my-key-ring \
    --key=my-key \
    --additional-authenticated-data-file=YOUR_ADDITIONAL_AUTHENTICATED_DATA_FILEPATH_AND_FILENAME \
    --ciphertext-file=YOUR_FILEPATH_AND_FILENAME_TO_DECRYPT \
    --plaintext-file=YOUR_FILEPATH_AND_FILENAME_TO_DECRYPT.dec

Protocol

Decrypted text that is returned in the JSON from Cloud KMS is base64-encoded. For information on encoding and decoding using base64, see Base64 Encoding.

To decrypt encrypted data, make a POST request and provide the appropriate project and key information and specify the encrypted (cipher) text to be decrypted in the ciphertext field of the request body. Replace YOUR_API_KEY with a valid API key. For information on generating an API key, see [Accessing the API][accessing-the-api].

POST https://cloudkms.googleapis.com/v1/projects/project_id/locations/global/keyRings/keyring_name/cryptoKeys/cryptoKey_name:decrypt&key=YOUR_API_KEY
{
  "ciphertext": "CiQAhMwwBo61cHas7dDgifrUFs5zNzBJ2uZtVFq4ZPEl6fUVT4kSmQ...",
}

Here is an example using curl:

curl -s -X POST "https://cloudkms.googleapis.com/v1/projects/YOUR_PROJECT_ID/locations/global/keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_CRYPTOKEY_NAME:decrypt" \
  -d "{\"ciphertext\":\"ENCRYPTED_CONTENT\"}" \
  -H "Authorization:Bearer YOUR_API_KEY"\
  -H "Content-Type:application/json"

C#

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

    public static object Decrypt(string projectId, string locationId, string keyRingId, string cryptoKeyId,
string ciphertextFile, string plaintextFile)
    {
        var cloudKms = CreateAuthorizedClient();
        // Generate the full path of the crypto key to use for encryption.
        var cryptoKey = $"projects/{projectId}/locations/{locationId}/keyRings/{keyRingId}/cryptoKeys/{cryptoKeyId}";
        DecryptRequest decryptRequest = new DecryptRequest();
        byte[] ciphertext = File.ReadAllBytes(ciphertextFile);
        decryptRequest.Ciphertext = Convert.ToBase64String(ciphertext);
        Console.WriteLine($"dataToDecrypt.Ciphertext: {decryptRequest.Ciphertext}");
        var result = cloudKms.Projects.Locations.KeyRings.CryptoKeys.Decrypt(name: cryptoKey, body: decryptRequest).Execute();
        // Output decrypted data to a file.
        File.WriteAllBytes(plaintextFile, Convert.FromBase64String(result.Plaintext));
        Console.Write($"Decrypted file created: {plaintextFile}");
        return 0;
    }

Go

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

func decrypt(projectID, locationID, keyRingID, cryptoKeyID string, ciphertext []byte) ([]byte, error) {
	ctx := context.Background()
	client, err := google.DefaultClient(ctx, cloudkms.CloudPlatformScope)
	if err != nil {
		return nil, err
	}

	cloudkmsService, err := cloudkms.New(client)
	if err != nil {
		return nil, err
	}

	parentName := fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s",
		projectID, locationID, keyRingID, cryptoKeyID)

	req := &cloudkms.DecryptRequest{
		Ciphertext: base64.StdEncoding.EncodeToString(ciphertext),
	}
	resp, err := cloudkmsService.Projects.Locations.KeyRings.CryptoKeys.Decrypt(parentName, req).Do()
	if err != nil {
		return nil, err
	}
	return base64.StdEncoding.DecodeString(resp.Plaintext)
}

Java

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Decrypts the provided ciphertext with the specified crypto key.
 */
public static byte[] decrypt(String projectId, String locationId, String keyRingId,
    String cryptoKeyId, byte[] ciphertext)
    throws IOException {
  // Create the Cloud KMS client.
  CloudKMS kms = createAuthorizedClient();

  // The resource name of the cryptoKey
  String cryptoKeyName = String.format(
      "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s",
      projectId, locationId, keyRingId, cryptoKeyId);

  DecryptRequest request = new DecryptRequest().encodeCiphertext(ciphertext);
  DecryptResponse response = kms.projects().locations().keyRings().cryptoKeys()
      .decrypt(cryptoKeyName, request)
      .execute();

  return response.decodePlaintext();
}

Node.js

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

const fs = require('fs');

// Your Google Cloud Platform project ID
// const projectId = 'YOUR_PROJECT_ID';

// The location of the crypto key's key ring, e.g. "global"
// const locationId = 'global';

// The name of the crypto key's key ring, e.g. "my-key-ring"
// const keyRingId = 'my-key-ring';

// The name of the crypto key, e.g. "my-key"
// const cryptoKeyId = 'my-key';

// The path to the file to decrypt, e.g. "./path/to/plaintext.txt.encrypted"
// const ciphertextFileName = './path/to/plaintext.txt.encrypted';

// The path where the decrypted file should be written, e.g. "./path/to/plaintext.txt.decrypted"
// const plaintextFileName = './path/to/plaintext.txt.decrypted';

// Builds and authorizes a Cloud KMS client
buildAndAuthorizeService((err, cloudkms) => {
  if (err) {
    console.log(err);
    return;
  }

  // Reads the file to be decrypted
  fs.readFile(ciphertextFileName, (err, contentsBuffer) => {
    if (err) {
      console.log(err);
      return;
    }

    const request = {
      // This will be a path parameter in the request URL
      name: `projects/${projectId}/locations/${locationId}/keyRings/${keyRingId}/cryptoKeys/${cryptoKeyId}`,
      // This will be the request body
      resource: {
        ciphertext: contentsBuffer.toString('base64')
      }
    };

    // Dencrypts the file using the specified crypto key
    cloudkms.projects.locations.keyRings.cryptoKeys.decrypt(request, (err, result) => {
      if (err) {
        console.log(err);
        return;
      }

      // Writes the dencrypted file to disk
      fs.writeFile(plaintextFileName, Buffer.from(result.plaintext, 'base64'), (err) => {
        if (err) {
          console.log(err);
          return;
        }

        console.log(`Decrypted ${ciphertextFileName}, result saved to ${plaintextFileName}.`);
      });
    });
  });
});

function buildAndAuthorizeService (callback) {
  // Imports the Google APIs client library
  const google = require('googleapis');

  // Acquires credentials
  google.auth.getApplicationDefault((err, authClient) => {
    if (err) {
      callback(err);
      return;
    }

    if (authClient.createScopedRequired && authClient.createScopedRequired()) {
      authClient = authClient.createScoped([
        'https://www.googleapis.com/auth/cloud-platform'
      ]);
    }

    // Instantiates an authorized client
    const cloudkms = google.cloudkms({
      version: 'v1',
      auth: authClient
    });

    callback(null, cloudkms);
  });
}

PHP

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Decrypt a text file.
 *
 * @param string $projectId
 * @param string $keyRingId
 * @param string $cryptoKeyId
 * @param string $ciphertextFileName The path to the ciphertext file to decrypt.
 * @param string $plaintextFileName The path to write the decrypted plaintext file.
 * @param string $locationId [optional]
 * @return null
 */
function decrypt($projectId, $keyRingId, $cryptoKeyId, $ciphertextFileName, $plaintextFileName, $locationId = 'global')
{
    // Instantiate the client, authenticate, and add scopes.
    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();
    $client->addScope('https://www.googleapis.com/auth/cloud-platform');

    // Create the Cloud KMS client.
    $kms = new Google_Service_CloudKMS($client);

    // The resource name of the cryptokey.
    $name = sprintf('projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s',
        $projectId,
        $locationId,
        $keyRingId,
        $cryptoKeyId
    );

    // Use the KMS API to decrypt the text.
    $ciphertext = base64_encode(file_get_contents($ciphertextFileName));
    $request = new Google_Service_CloudKMS_DecryptRequest();
    $request->setCiphertext($ciphertext);
    $response = $kms->projects_locations_keyRings_cryptoKeys->decrypt(
        $name,
        $request
    );

    // Write the decrypted text to a file.
    file_put_contents($plaintextFileName, base64_decode($response['plaintext']));
    printf('Saved decrypted text to %s' . PHP_EOL, $plaintextFileName);
}

Python

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

def decrypt(project_id, location_id, key_ring_id, crypto_key_id,
            ciphertext_file_name, plaintext_file_name):
    """Decrypts data from ciphertext_file_name that was previously encrypted
    using the provided CryptoKey and saves it to plaintext_file_name."""

    # Creates an API client for the KMS API.
    kms_client = googleapiclient.discovery.build('cloudkms', 'v1')

    # The resource name of the CryptoKey.
    name = 'projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}'.format(
        project_id, location_id, key_ring_id, crypto_key_id)

    # Read encrypted data from the input file.
    with io.open(ciphertext_file_name, 'rb') as ciphertext_file:
        ciphertext = ciphertext_file.read()

    # Use the KMS API to decrypt the data.
    crypto_keys = kms_client.projects().locations().keyRings().cryptoKeys()
    request = crypto_keys.decrypt(
        name=name,
        body={'ciphertext': base64.b64encode(ciphertext).decode('ascii')})
    response = request.execute()
    plaintext = base64.b64decode(response['plaintext'].encode('ascii'))

    # Write the decrypted data to a file.
    with io.open(plaintext_file_name, 'wb') as plaintext_file:
        plaintext_file.write(plaintext)

    print('Saved plaintext to {}.'.format(plaintext_file_name))

Ruby

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

# project_id    = "Your Google Cloud project ID"
# location_id   = "The location of the key ring"
# key_ring_id   = "The ID of the key ring"
# crypto_key_id = "The ID of the crypto key"
# ciphertext_file = "File to decrypt"
# plaintext_file  = "File to store decrypted data"

require "google/apis/cloudkms_v1"

# Initialize the client and authenticate with the specified scope
Cloudkms = Google::Apis::CloudkmsV1
kms_client = Cloudkms::CloudKMSService.new
kms_client.authorization = Google::Auth.get_application_default(
  "https://www.googleapis.com/auth/cloud-platform"
)

# The resource name of the crypto key
resource = "projects/#{project_id}/locations/#{location_id}/" +
           "keyRings/#{key_ring_id}/cryptoKeys/#{crypto_key_id}"

# Read the encrypted data from the file
ciphertext = File.read ciphertext_file

request = Cloudkms::DecryptRequest.new ciphertext: ciphertext

# Use the KMS API to decrypt the data
response = kms_client.decrypt_crypto_key resource, request

# Write the decrypted text to the output file
File.write plaintext_file, response.plaintext

puts "Saved decrypted #{ciphertext_file} as #{plaintext_file}"

Re-encrypt the data using the new primary CryptoKeyVersion

Cloud KMS automatically uses the new primary CryptoKeyVersion to encrypt data. The following examples show how to encrypt the data. This is the same encryption code used in Encrypting and Decrypting.

Command-line

To encrypt data, provide the appropriate key information, specify the name of the plaintext file to encrypt, and specify the name of the file that will contain the encrypted content.

gcloud kms encrypt \
    --location=global  \
    --keyring=my-key-ring \
    --key=my-key \
    --plaintext-file=YOUR_FILEPATH_AND_FILENAME_TO_ENCRYPT.dec \
    --ciphertext-file=YOUR_FILEPATH_AND_FILENAME.enc

The plaintext file must not be larger than 64 KiB.

The encrypt command supports an optional --additional-authenticated-data-file flag to specify a file that contains additional authenticated data. The additional authenticated data file must not be larger than 64 KiB.

If --plaintext-file or --additional-authenticated-data-file is set to -, that file is read from stdin. Similarly, if --ciphertext-file is set to -, the ciphertext is written to stdout.

The encrypt command supports an optional --version flag to indicate the version of the key to use for encryption. By default, the primary version is used.

The following encrypt example shows how to specify a version key and additional authenticated data.

gcloud kms encrypt \
    --location=global  \
    --keyring=my-key-ring \
    --key=my-key \
    --version=my-key-version \
    --additional-authenticated-data-file=YOUR_ADDITIONAL_AUTHENTICATED_DATA_FILEPATH_AND_FILENAME \
    --plaintext-file=YOUR_FILEPATH_AND_FILENAME_TO_ENCRYPT.dec \
    --ciphertext-file=YOUR_FILEPATH_AND_FILENAME.enc

Protocol

Content to be encrypted that is sent to Cloud KMS in JSON must be base64-encoded. For information on encoding and decoding using base64, see Base64 Encoding.

To encrypt data, make a POST request and provide the appropriate project and key information and specify the base64-encoded text to be encrypted in the plaintext field of the request body. Replace YOUR_API_KEY with a valid API key. For information on generating an API key, see [Accessing the API][accessing-the-api].

POST https://cloudkms.googleapis.com/v1/projects/project_id/locations/global/keyRings/keyring_name/cryptoKeys/cryptoKey_name:encrypt&key=YOUR_API_KEY
{
  "plaintext": "BASE64_ENCODED_INPUT",
}

Here is an example using curl:

curl -s -X POST "https://cloudkms.googleapis.com/v1/projects/YOUR_PROJECT_ID/locations/global/keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_CRYPTOKEY_NAME:encrypt" \
  -d "{\"plaintext\":\"BASE64_ENCODED_INPUT\"}" \
  -H "Authorization:Bearer YOUR_API_KEY"\
  -H "Content-Type:application/json"

C#

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

        public static object Encrypt(string projectId, string locationId, string keyRingId, string cryptoKeyId,
string plaintextFile, string ciphertextFile)
        {
            var cloudKms = CreateAuthorizedClient();
            // Generate the full path of the crypto key to use for encryption.
            var cryptoKey = $"projects/{projectId}/locations/{locationId}/keyRings/{keyRingId}/cryptoKeys/{cryptoKeyId}";
            EncryptRequest encryptRequest = new EncryptRequest();
            byte[] plaintext = File.ReadAllBytes(plaintextFile);
            encryptRequest.Plaintext = Convert.ToBase64String(plaintext);
            Console.WriteLine($"dataToEncrypt.Plaintext: {encryptRequest.Plaintext}");
            var result = cloudKms.Projects.Locations.KeyRings.CryptoKeys.Encrypt(name: cryptoKey, body: encryptRequest).Execute();
            // Output encrypted data to a file.
            File.WriteAllBytes(ciphertextFile, Convert.FromBase64String(result.Ciphertext));
            Console.Write($"Encrypted file created: {ciphertextFile}");
            return 0;
        }

Go

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

func encrypt(projectID, locationID, keyRingID, cryptoKeyID string, plaintext []byte) ([]byte, error) {
	ctx := context.Background()
	client, err := google.DefaultClient(ctx, cloudkms.CloudPlatformScope)
	if err != nil {
		return nil, err
	}

	cloudkmsService, err := cloudkms.New(client)
	if err != nil {
		return nil, err
	}

	parentName := fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s",
		projectID, locationID, keyRingID, cryptoKeyID)

	req := &cloudkms.EncryptRequest{
		Plaintext: base64.StdEncoding.EncodeToString(plaintext),
	}
	resp, err := cloudkmsService.Projects.Locations.KeyRings.CryptoKeys.Encrypt(parentName, req).Do()
	if err != nil {
		return nil, err
	}

	return base64.StdEncoding.DecodeString(resp.Ciphertext)
}

Java

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Encrypts the given plaintext using the specified crypto key.
 */
public static byte[] encrypt(
    String projectId, String locationId, String keyRingId, String cryptoKeyId, byte[] plaintext)
    throws IOException {
  // The resource name of the cryptoKey
  String resourceName = String.format(
      "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s",
      projectId, locationId, keyRingId, cryptoKeyId);

  // Create the Cloud KMS client.
  CloudKMS kms = createAuthorizedClient();

  EncryptRequest request = new EncryptRequest().encodePlaintext(plaintext);
  EncryptResponse response = kms.projects().locations().keyRings().cryptoKeys()
      .encrypt(resourceName, request)
      .execute();

  return response.decodeCiphertext();
}

Node.js

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

const fs = require('fs');

// Your Google Cloud Platform project ID
// const projectId = 'YOUR_PROJECT_ID';

// The location of the crypto key's key ring, e.g. "global"
// const locationId = 'global';

// The name of the crypto key's key ring, e.g. "my-key-ring"
// const keyRingId = 'my-key-ring';

// The name of the crypto key, e.g. "my-key"
// const cryptoKeyId = 'my-key';

// The path to the file to encrypt, e.g. "./path/to/plaintext.txt"
// const plaintextFileName = './path/to/plaintext.txt';

// The path where the encrypted file should be written, e.g. "./path/to/plaintext.txt.encrypted"
// const ciphertextFileName = './path/to/plaintext.txt.encrypted';

// Builds and authorizes a Cloud KMS client
buildAndAuthorizeService((err, cloudkms) => {
  if (err) {
    console.log(err);
    return;
  }

  // Reads the file to be encrypted
  fs.readFile(plaintextFileName, (err, contentsBuffer) => {
    if (err) {
      console.log(err);
      return;
    }

    const request = {
      // This will be a path parameter in the request URL
      name: `projects/${projectId}/locations/${locationId}/keyRings/${keyRingId}/cryptoKeys/${cryptoKeyId}`,
      // This will be the request body
      resource: {
        plaintext: contentsBuffer.toString('base64')
      }
    };

    // Encrypts the file using the specified crypto key
    cloudkms.projects.locations.keyRings.cryptoKeys.encrypt(request, (err, result) => {
      if (err) {
        console.log(err);
        return;
      }

      // Writes the encrypted file to disk
      fs.writeFile(ciphertextFileName, Buffer.from(result.ciphertext, 'base64'), (err) => {
        if (err) {
          console.log(err);
          return;
        }

        console.log(`Encrypted ${plaintextFileName} using ${result.name}.`);
        console.log(`Result saved to ${ciphertextFileName}.`);
      });
    });
  });
});

function buildAndAuthorizeService (callback) {
  // Imports the Google APIs client library
  const google = require('googleapis');

  // Acquires credentials
  google.auth.getApplicationDefault((err, authClient) => {
    if (err) {
      callback(err);
      return;
    }

    if (authClient.createScopedRequired && authClient.createScopedRequired()) {
      authClient = authClient.createScoped([
        'https://www.googleapis.com/auth/cloud-platform'
      ]);
    }

    // Instantiates an authorized client
    const cloudkms = google.cloudkms({
      version: 'v1',
      auth: authClient
    });

    callback(null, cloudkms);
  });
}

PHP

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Encrypt a text file.
 *
 * @param string $projectId
 * @param string $keyRingId
 * @param string $cryptoKeyId
 * @param string $plaintextFileName The path to the file containing plaintext to encrypt.
 * @param string $ciphertextFileName The path to write the ciphertext.
 * @param string $locationId [optional]
 * @return null
 */
function encrypt($projectId, $keyRingId, $cryptoKeyId, $plaintextFileName, $ciphertextFileName, $locationId = 'global')
{
    // Instantiate the client, authenticate, and add scopes.
    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();
    $client->addScope('https://www.googleapis.com/auth/cloud-platform');

    // Create the Cloud KMS client.
    $kms = new Google_Service_CloudKMS($client);

    // The resource name of the cryptokey.
    $name = sprintf('projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s',
        $projectId,
        $locationId,
        $keyRingId,
        $cryptoKeyId
    );

    // Use the KMS API to encrypt the text.
    $encoded = base64_encode(file_get_contents($plaintextFileName));
    $request = new Google_Service_CloudKMS_EncryptRequest();
    $request->setPlaintext($encoded);
    $response = $kms->projects_locations_keyRings_cryptoKeys->encrypt(
        $name,
        $request
    );

    // Write the encrypted text to a file.
    file_put_contents($ciphertextFileName, base64_decode($response['ciphertext']));
    printf('Saved encrypted text to %s' . PHP_EOL, $ciphertextFileName);
}

Python

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

def encrypt(project_id, location_id, key_ring_id, crypto_key_id,
            plaintext_file_name, ciphertext_file_name):
    """Encrypts data from plaintext_file_name using the provided CryptoKey and
    saves it to ciphertext_file_name so it can only be recovered with a call to
    decrypt.
    """

    # Creates an API client for the KMS API.
    kms_client = googleapiclient.discovery.build('cloudkms', 'v1')

    # The resource name of the CryptoKey.
    name = 'projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}'.format(
        project_id, location_id, key_ring_id, crypto_key_id)

    # Read data from the input file.
    with io.open(plaintext_file_name, 'rb') as plaintext_file:
        plaintext = plaintext_file.read()

    # Use the KMS API to encrypt the data.
    crypto_keys = kms_client.projects().locations().keyRings().cryptoKeys()
    request = crypto_keys.encrypt(
        name=name,
        body={'plaintext': base64.b64encode(plaintext).decode('ascii')})
    response = request.execute()
    ciphertext = base64.b64decode(response['ciphertext'].encode('ascii'))

    # Write the encrypted data to a file.
    with io.open(ciphertext_file_name, 'wb') as ciphertext_file:
        ciphertext_file.write(ciphertext)

    print('Saved ciphertext to {}.'.format(ciphertext_file_name))

Ruby

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

# project_id      = "Your Google Cloud project ID"
# location_id     = "The location of the key ring"
# key_ring_id     = "The ID of the key ring"
# crypto_key_id   = "The ID of the crypto key"
# plaintext_file  = "File to encrypt"
# ciphertext_file = "File to store encrypted input data"

require "google/apis/cloudkms_v1"

# Initialize the client and authenticate with the specified scope
Cloudkms = Google::Apis::CloudkmsV1
kms_client = Cloudkms::CloudKMSService.new
kms_client.authorization = Google::Auth.get_application_default(
  "https://www.googleapis.com/auth/cloud-platform"
)

# The resource name of the crypto key
resource = "projects/#{project_id}/locations/#{location_id}/" +
           "keyRings/#{key_ring_id}/cryptoKeys/#{crypto_key_id}"

# Read the secret data from the file
plaintext = File.read plaintext_file

request = Cloudkms::EncryptRequest.new plaintext: plaintext

# Use the KMS API to encrypt the data
response = kms_client.encrypt_crypto_key resource, request

# Write the encrypted text to the output file
File.write ciphertext_file, response.ciphertext

puts "Saved encrypted #{plaintext_file} as #{ciphertext_file}"

Disable or schedule destruction of the prior CryptoKeyVersion

If you rotated your CryptoKey in response to a suspected incident, after you have re-encrypted the data, disable or schedule destruction of the prior CryptoKeyVersion.

Disable an enabled CryptoKeyVersion

Only a CryptoKeyVersion which is Enabled can be Disabled. This is done with the method UpdateCryptoKeyVersion.

Command-line

To disable version "42" of CryptoKey "answer" in KeyRing "answers"

gcloud kms keys versions disable 42 --location global --keyring answers --key answer

C#

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

      public static object DisableCryptoKeyVersion(string projectId, string locationId, string keyRingId, string cryptoKeyId, string versionId)
      {
          var cloudKms = CreateAuthorizedClient();
          // Generate the full path of the parent to use for disabling the crypto key Version.
          var parent = $"projects/{projectId}/locations/{locationId}/keyRings/{keyRingId}/cryptoKeys/{cryptoKeyId}/cryptoKeyVersions/{versionId}";
          // Get crypto key version.
          var request = new ProjectsResource.LocationsResource.KeyRingsResource.CryptoKeysResource
              .CryptoKeyVersionsResource.GetRequest(cloudKms, parent);
          var result = request.Execute();
          result.State = "DISABLED";
          var patchRequest = new ProjectsResource.LocationsResource.KeyRingsResource.CryptoKeysResource
              .CryptoKeyVersionsResource.PatchRequest(cloudKms, result, parent);
          patchRequest.UpdateMask = "state";
          var patchResult = patchRequest.Execute();
          Console.Write($"Disabled Crypto Key Version: {patchResult.Name}");
          return 0;
      }

Go

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

func disableCryptoKeyVersion(project, keyRing, key, version string) error {
	ctx := context.Background()
	authedClient, err := google.DefaultClient(ctx, cloudkms.CloudPlatformScope)
	if err != nil {
		return err
	}
	client, err := cloudkms.New(authedClient)
	if err != nil {
		return err
	}
	location := "global"
	parent := fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeyVersions/%s",
		project, location, keyRing, version)

	_, err = client.Projects.Locations.KeyRings.CryptoKeys.CryptoKeyVersions.Patch(
		parent, &cloudkms.CryptoKeyVersion{
			State: "DISABLED",
		}).UpdateMask("state").Do()
	if err != nil {
		return err
	}
	log.Print("Disabled crypto key version.")

	return nil
}

Java

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Disables the given version of the crypto key.
 */
public static CryptoKeyVersion disableCryptoKeyVersion(
    String projectId, String locationId, String keyRingId, String cryptoKeyId, String version)
    throws IOException {
  // Create the Cloud KMS client.
  CloudKMS kms = createAuthorizedClient();

  // The resource name of the cryptoKey version
  String cryptoKeyVersion = String.format(
      "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s",
      projectId, locationId, keyRingId, cryptoKeyId, version);

  CryptoKeyVersion newVersionState = new CryptoKeyVersion()
      .setState("DISABLED");

  CryptoKeyVersion response = kms.projects().locations().keyRings().cryptoKeys()
      .cryptoKeyVersions()
      .patch(cryptoKeyVersion, newVersionState)
      .setUpdateMask("state")
      .execute();

  System.out.println(response);
  return response;
}

Node.js

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

// Your Google Cloud Platform project ID
// const projectId = 'YOUR_PROJECT_ID';

// The location of the crypto key versions's key ring, e.g. "global"
// const locationId = 'global';

// The name of the crypto key version's key ring, e.g. "my-key-ring"
// const keyRingId = 'my-key-ring';

// The name of the version's crypto key, e.g. "my-key"
// const cryptoKeyId = 'my-key';

// The version's id, e.g. 123
// const version = 123;

// Builds and authorizes a Cloud KMS client
buildAndAuthorizeService((err, cloudkms) => {
  if (err) {
    console.log(err);
    return;
  }

  let request = {
    // This will be a path parameter in the request URL
    name: `projects/${projectId}/locations/${locationId}/keyRings/${keyRingId}/cryptoKeys/${cryptoKeyId}/cryptoKeyVersions/${version}`
  };

  // Gets a crypto key version
  cloudkms.projects.locations.keyRings.cryptoKeys.cryptoKeyVersions.get(request, (err, cryptoKeyVersion) => {
    if (err) {
      console.log(err);
      return;
    }

    cryptoKeyVersion.state = 'DISABLED';

    request = {
      // This will be a path parameter in the request URL
      name: request.name,
      // This will be a query parameter in the request URL
      updateMask: 'state',
      // This will be the request body
      resource: cryptoKeyVersion
    };

    // Disables a crypto key version
    cloudkms.projects.locations.keyRings.cryptoKeys.cryptoKeyVersions.patch(request, (err, cryptoKeyVersion) => {
      if (err) {
        console.log(err);
        return;
      }

      console.log(`Crypto key version ${cryptoKeyVersion.name} disabled.`);
    });
  });
});

function buildAndAuthorizeService (callback) {
  // Imports the Google APIs client library
  const google = require('googleapis');

  // Acquires credentials
  google.auth.getApplicationDefault((err, authClient) => {
    if (err) {
      callback(err);
      return;
    }

    if (authClient.createScopedRequired && authClient.createScopedRequired()) {
      authClient = authClient.createScoped([
        'https://www.googleapis.com/auth/cloud-platform'
      ]);
    }

    // Instantiates an authorized client
    const cloudkms = google.cloudkms({
      version: 'v1',
      auth: authClient
    });

    callback(null, cloudkms);
  });
}

PHP

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Disable a CryptoKey version.
 *
 * @param string $projectId
 * @param string $keyRingId
 * @param string $cryptoKeyId
 * @param int $version
 * @param string $locationId [optional]
 * @return null
 */
function disable_cryptokey_version($projectId, $keyRingId, $cryptoKeyId, $version, $locationId = 'global')
{
    // Instantiate the client, authenticate, and add scopes.
    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();
    $client->addScope('https://www.googleapis.com/auth/cloud-platform');

    // Create the Cloud KMS client.
    $kms = new Google_Service_CloudKMS($client);

    // The resource name of the KeyRing associated with the CryptoKey.
    $parent = sprintf('projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s',
        $projectId,
        $locationId,
        $keyRingId,
        $cryptoKeyId,
        $version
    );

    // Disable the CryptoKey version.
    $cryptoKeyVersion = $kms->projects_locations_keyRings_cryptoKeys_cryptoKeyVersions
        ->get($parent);
    $cryptoKeyVersion->setState('DISABLED');

    $kms->projects_locations_keyRings_cryptoKeys_cryptoKeyVersions->patch(
        $parent,
        $cryptoKeyVersion,
        ['updateMask' => 'state']
    );

    printf('Disabled version %s for cryptoKey %s in keyRing %s' . PHP_EOL, $version, $cryptoKeyId, $keyRingId);
}

Python

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

def disable_crypto_key_version(project_id, location_id, key_ring_id,
                               crypto_key_id, version_id):
    """Disables a CryptoKeyVersion associated with a given CryptoKey and
    KeyRing."""

    # Creates an API client for the KMS API.
    kms_client = googleapiclient.discovery.build('cloudkms', 'v1')

    # Construct the resource name of the CryptoKeyVersion.
    name = (
        'projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}/'
        'cryptoKeyVersions/{}'
        .format(
            project_id, location_id, key_ring_id, crypto_key_id, version_id))

    # Use the KMS API to disable the CryptoKeyVersion.
    crypto_keys = kms_client.projects().locations().keyRings().cryptoKeys()
    request = crypto_keys.cryptoKeyVersions().patch(
        name=name, body={'state': 'DISABLED'}, updateMask='state')
    response = request.execute()

    print('CryptoKeyVersion {}\'s state has been set to {}.'.format(
        name, response['state']))

Ruby

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

# project_id    = "Your Google Cloud project ID"
# location_id   = "The location of the key ring"
# key_ring_id   = "The ID of the key ring"
# crypto_key_id = "The ID of the crypto key"
# version_id    = "Version of the crypto key"

require "google/apis/cloudkms_v1"

# Initialize the client and authenticate with the specified scope
Cloudkms = Google::Apis::CloudkmsV1
kms_client = Cloudkms::CloudKMSService.new
kms_client.authorization = Google::Auth.get_application_default(
  "https://www.googleapis.com/auth/cloud-platform"
)

# The resource name of the crypto key version
resource = "projects/#{project_id}/locations/#{location_id}/" +
           "keyRings/#{key_ring_id}/cryptoKeys/#{crypto_key_id}/" +
           "cryptoKeyVersions/#{version_id}"

# Get a crypto key version
crypto_key_version = kms_client.get_project_location_key_ring_crypto_key_crypto_key_version resource

# Set the primary version state as disabled for update
crypto_key_version.state = "DISABLED"

# Disable the crypto key version
kms_client.patch_project_location_key_ring_crypto_key_crypto_key_version(
  resource,
  crypto_key_version, update_mask: "state"
)

puts "Disabled version #{version_id} of #{crypto_key_id}"

Schedule a CryptoKeyVersion for destruction

Only CryptoKeyVersions which are Enabled or Disabled can be Scheduled for destruction. This is done with the method DestroyCryptoKeyVersion.

To prevent accidents, and damage from malicious individuals, when DestroyCryptoKeyVersion is used, the key material is NOT immediately Destroyed. Rather, the CryptoKeyVersion moves to Scheduled for destruction for 24 hours, after which it is automatically destroyed. There is no way to override this safety fallback. If you decide within 24 hours of scheduling the destruction that you do not want the destruction to occur, you can restore the CryptoKeyVersion.

Destruction is removal of the key material, but a record of the version still exists (e.g., the version number cannot be reused). This is NOT reversible - any data encrypted with this version will not be recoverable.

Command-line

Destroy version "42" of CryptoKey "answer" in KeyRing "answers"

gcloud kms keys versions destroy 42 --location global --keyring answers --key answer

C#

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

      public static object DestroyCryptoKeyVersion(string projectId, string locationId, string keyRingId, string cryptoKeyId, string versionId)
      {
          var cloudKms = CreateAuthorizedClient();
          // Generate the full path of the parent to use for destroying the crypto key Version.
          var parent = $"projects/{projectId}/locations/{locationId}/keyRings/{keyRingId}/cryptoKeys/{cryptoKeyId}/cryptoKeyVersions/{versionId}";
          DestroyCryptoKeyVersionRequest destroyRequest = new DestroyCryptoKeyVersionRequest();
          // Destroy crypto key version.
          var request = new ProjectsResource.LocationsResource.KeyRingsResource.CryptoKeysResource
              .CryptoKeyVersionsResource.DestroyRequest(cloudKms, destroyRequest, parent);
          var result = request.Execute();
          Console.Write($"Destroyed Crypto Key Version: {result.Name}");
          return 0;
      }

Go

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

func destroyCryptoKeyVersion(project, keyRing, key, version string) error {
	ctx := context.Background()
	authedClient, err := google.DefaultClient(ctx, cloudkms.CloudPlatformScope)
	if err != nil {
		return err
	}
	client, err := cloudkms.New(authedClient)
	if err != nil {
		return err
	}
	location := "global"
	parent := fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeyVersions/%s",
		project, location, keyRing, version)

	_, err = client.Projects.Locations.KeyRings.CryptoKeys.CryptoKeyVersions.Destroy(
		parent, &cloudkms.DestroyCryptoKeyVersionRequest{}).Do()
	if err != nil {
		return err
	}
	log.Print("Destroyed crypto key version.")

	return nil
}

Java

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Marks the given version of a crypto key to be destroyed at a scheduled future point.
 */
public static CryptoKeyVersion destroyCryptoKeyVersion(
    String projectId, String locationId, String keyRingId, String cryptoKeyId, String version)
    throws IOException {
  // Create the Cloud KMS client.
  CloudKMS kms = createAuthorizedClient();

  // The resource name of the cryptoKey version
  String cryptoKeyVersion = String.format(
      "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s",
      projectId, locationId, keyRingId, cryptoKeyId, version);

  DestroyCryptoKeyVersionRequest destroyRequest = new DestroyCryptoKeyVersionRequest();

  CryptoKeyVersion destroyed = kms.projects().locations().keyRings().cryptoKeys()
      .cryptoKeyVersions()
      .destroy(cryptoKeyVersion, destroyRequest)
      .execute();

  System.out.println(destroyed);
  return destroyed;
}

Node.js

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

// Your Google Cloud Platform project ID
// const projectId = 'YOUR_PROJECT_ID';

// The location of the crypto key versions's key ring, e.g. "global"
// const locationId = 'global';

// The name of the crypto key version's key ring, e.g. "my-key-ring"
// const keyRingId = 'my-key-ring';

// The name of the version's crypto key, e.g. "my-key"
// const cryptoKeyId = 'my-key';

// The version's id, e.g. 123
// const version = 123;

// Builds and authorizes a Cloud KMS client
buildAndAuthorizeService((err, cloudkms) => {
  if (err) {
    console.log(err);
    return;
  }

  const request = {
    // This will be a path parameter in the request URL
    name: `projects/${projectId}/locations/${locationId}/keyRings/${keyRingId}/cryptoKeys/${cryptoKeyId}/cryptoKeyVersions/${version}`
  };

  // Destroys a crypto key version
  cloudkms.projects.locations.keyRings.cryptoKeys.cryptoKeyVersions.destroy(request, (err, cryptoKeyVersion) => {
    if (err) {
      console.log(err);
      return;
    }

    console.log(`Crypto key version ${cryptoKeyVersion.name} destroyed.`);
  });
});

function buildAndAuthorizeService (callback) {
  // Imports the Google APIs client library
  const google = require('googleapis');

  // Acquires credentials
  google.auth.getApplicationDefault((err, authClient) => {
    if (err) {
      callback(err);
      return;
    }

    if (authClient.createScopedRequired && authClient.createScopedRequired()) {
      authClient = authClient.createScoped([
        'https://www.googleapis.com/auth/cloud-platform'
      ]);
    }

    // Instantiates an authorized client
    const cloudkms = google.cloudkms({
      version: 'v1',
      auth: authClient
    });

    callback(null, cloudkms);
  });
}

PHP

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

/**
 * Destroy a CryptoKey version.
 *
 * @param string $projectId
 * @param string $keyRingId
 * @param string $cryptoKeyId
 * @param string $version
 * @param string $locationId [optional]
 * @return Google_Service_CloudKMS_CryptoKeyVersion
 */
function destroy_cryptokey_version($projectId, $keyRingId, $cryptoKeyId, $version, $locationId = 'global')
{
    // Instantiate the client, authenticate, and add scopes.
    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();
    $client->addScope('https://www.googleapis.com/auth/cloud-platform');

    // Create the Cloud KMS client.
    $kms = new Google_Service_CloudKMS($client);

    // The resource name of the CryptoKey version.
    $parent = sprintf('projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s',
        $projectId,
        $locationId,
        $keyRingId,
        $cryptoKeyId,
        $version
    );

    // Destroy the CryptoKey version.
    $request = new Google_Service_CloudKMS_DestroyCryptoKeyVersionRequest();
    $kms->projects_locations_keyRings_cryptoKeys_cryptoKeyVersions->destroy(
        $parent,
        $request
    );

    printf('Destroyed version %s for cryptoKey %s in keyRing %s' . PHP_EOL, $version, $cryptoKeyId, $keyRingId);
}

Python

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

def destroy_crypto_key_version(
        project_id, location_id, key_ring_id, crypto_key_id, version_id):
    """Schedules a CryptoKeyVersion associated with a given CryptoKey and
    KeyRing for destruction 24 hours in the future."""

    # Creates an API client for the KMS API.
    kms_client = googleapiclient.discovery.build('cloudkms', 'v1')

    # Construct the resource name of the CryptoKeyVersion.
    name = (
        'projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}/'
        'cryptoKeyVersions/{}'
        .format(
            project_id, location_id, key_ring_id, crypto_key_id, version_id))

    # Use the KMS API to schedule the CryptoKeyVersion for destruction.
    crypto_keys = kms_client.projects().locations().keyRings().cryptoKeys()
    request = crypto_keys.cryptoKeyVersions().destroy(name=name, body={})
    response = request.execute()

    print('CryptoKeyVersion {}\'s state has been set to {}.'.format(
        name, response['state']))

Ruby

For more on installing and creating a Cloud KMS client, refer to Cloud KMS Client Libraries.

# project_id    = "Your Google Cloud project ID"
# location_id   = "The location of the key ring"
# key_ring_id   = "The ID of the key ring"
# crypto_key_id = "The ID of the crypto key"
# version_id    = "Version of the crypto key"

require "google/apis/cloudkms_v1"

# Initialize the client and authenticate with the specified scope
Cloudkms = Google::Apis::CloudkmsV1
kms_client = Cloudkms::CloudKMSService.new
kms_client.authorization = Google::Auth.get_application_default(
  "https://www.googleapis.com/auth/cloud-platform"
)

# The resource name of the crypto key version
resource = "projects/#{project_id}/locations/#{location_id}/" +
           "keyRings/#{key_ring_id}/cryptoKeys/#{crypto_key_id}/" +
           "cryptoKeyVersions/#{version_id}"

# Destroy specific version of the crypto key
kms_client.destroy_crypto_key_version(
  resource,
  Cloudkms::DestroyCryptoKeyVersionRequest.new
)

puts "Destroyed version #{version_id} of #{crypto_key_id}"

Monitor your resources on the go

Get the Google Cloud Console app to help you manage your projects.

Send feedback about...

Cloud KMS Documentation