Rotate an encryption key

Rotate an encryption key.

Documentation pages that include this code sample

To view the code sample used in context, see the following documentation:

Code sample

C#

For more information, see the Cloud Storage C# API reference documentation.


using Google.Cloud.Storage.V1;
using System;
using System.IO;

public class ObjectRotateEncryptionKeySample
{
    public void ObjectRotateEncryptionKey(
        string bucketName = "your-unique-bucket-name",
        string objectName = "your-object-name",
        string currrentEncryptionKey = "TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=",
        string newEncryptionKey = "ARbt/judaq+VmtXzAsc83J4z5kFmWJ6NdAPQuleuB7g=")
    {
        var storage = StorageClient.Create();

        using var outputStream = new MemoryStream();
        storage.DownloadObject(bucketName, objectName, outputStream, new DownloadObjectOptions()
        {
            EncryptionKey = EncryptionKey.Create(Convert.FromBase64String(currrentEncryptionKey))
        });

        outputStream.Position = 0;

        storage.UploadObject(bucketName, objectName, null, outputStream, new UploadObjectOptions()
        {
            EncryptionKey = EncryptionKey.Create(Convert.FromBase64String(newEncryptionKey))
        });

        Console.WriteLine($"Rotated encryption key for object  {objectName} in bucket {bucketName}");
    }
}

C++

For more information, see the Cloud Storage C++ API reference documentation.

namespace gcs = ::google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string const& bucket_name,
   std::string const& object_name, std::string const& old_key_base64,
   std::string const& new_key_base64) {
  StatusOr<gcs::ObjectMetadata> object_metadata =
      client.RewriteObjectBlocking(
          bucket_name, object_name, bucket_name, object_name,
          gcs::SourceEncryptionKey::FromBase64Key(old_key_base64),
          gcs::EncryptionKey::FromBase64Key(new_key_base64));

  if (!object_metadata) {
    throw std::runtime_error(object_metadata.status().message());
  }

  std::cout << "Rotated key on object " << object_metadata->name()
            << " in bucket " << object_metadata->bucket()
            << "\nFull Metadata: " << *object_metadata << "\n";
}

Go

For more information, see the Cloud Storage Go API reference documentation.

ctx := context.Background()

client, err := storage.NewClient(ctx)
if err != nil {
	return err
}
obj := client.Bucket(bucket).Object(object)

ctx, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()
// obj is encrypted with key, we are encrypting it with the newKey.
_, err = obj.Key(newKey).CopierFrom(obj.Key(key)).Run(ctx)
if err != nil {
	return err
}

Java

For more information, see the Cloud Storage Java API reference documentation.

import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;

public class RotateObjectEncryptionKey {
  public static void rotateObjectEncryptionKey(
      String projectId,
      String bucketName,
      String objectName,
      String oldEncryptionKey,
      String newEncryptionKey) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    // The ID of your GCS object
    // String objectName = "your-object-name";

    // The Base64 encoded AES-256 encryption key originally used to encrypt the object. See the
    // documentation
    // on Customer-Supplied Encryption keys for more info:
    // https://cloud.google.com/storage/docs/encryption/using-customer-supplied-keys
    // String oldEncryptionKey = "TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g="

    // The new encryption key to use
    // String newEncryptionKey = "0mMWhFvQOdS4AmxRpo8SJxXn5MjFhbz7DkKBUdUIef8="

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    BlobId blobId = BlobId.of(bucketName, objectName);
    // You can't change an object's encryption key directly, the only way is to overwrite the object
    Storage.CopyRequest request =
        Storage.CopyRequest.newBuilder()
            .setSource(blobId)
            .setSourceOptions(Storage.BlobSourceOption.decryptionKey(oldEncryptionKey))
            .setTarget(blobId, Storage.BlobTargetOption.encryptionKey(newEncryptionKey))
            .build();
    storage.copy(request);

    System.out.println(
        "Rotated encryption key for object " + objectName + "in bucket " + bucketName);
  }
}

Node.js

For more information, see the Cloud Storage Node.js API reference documentation.

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The ID of your GCS file
// const fileName = 'your-file-name';

// The Base64 encoded AES-256 encryption key originally used to encrypt the
// object. See the documentation on Customer-Supplied Encryption keys for
// more info:
// https://cloud.google.com/storage/docs/encryption/using-customer-supplied-keys
// The Base64 encoded AES-256 encryption key originally used to encrypt the
// const oldKey = 'TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=';

// The new encryption key to use
// const newKey = '0mMWhFvQOdS4AmxRpo8SJxXn5MjFhbz7DkKBUdUIef8=';

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

async function rotateEncryptionKey() {
  await storage
    .bucket(bucketName)
    .file(fileName, {
      encryptionKey: Buffer.from(oldKey, 'base64'),
    })
    .rotateEncryptionKey({
      encryptionKey: Buffer.from(newKey, 'base64'),
    });

  console.log('Encryption key rotated successfully');
}

rotateEncryptionKey().catch(console.error);

PHP

For more information, see the Cloud Storage PHP API reference documentation.

use Google\Cloud\Storage\StorageClient;

/**
 * Change the encryption key used to store an existing object.
 *
 * @param string $bucketName The name of your Cloud Storage bucket.
 * @param string $objectName The name of your Cloud Storage object.
 * @param string $oldBase64EncryptionKey The Base64 encoded AES-256 encryption
 *     key originally used to encrypt the object. See the documentation on
 *     Customer-Supplied Encryption keys for more info:
 *     https://cloud.google.com/storage/docs/encryption/using-customer-supplied-keys
 * @param string $newBase64EncryptionKey The new base64 encoded encryption key.
 */
function rotate_encryption_key(
    $bucketName,
    $objectName,
    $oldBase64EncryptionKey,
    $newBase64EncryptionKey
) {
    // $bucketName = 'my-bucket';
    // $objectName = 'my-object';
    // $oldbase64EncryptionKey = 'TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=';
    // $newBase64EncryptionKey = '0mMWhFvQOdS4AmxRpo8SJxXn5MjFhbz7DkKBUdUIef8=';

    $storage = new StorageClient();
    $object = $storage->bucket($bucketName)->object($objectName);

    $rewrittenObject = $object->rewrite($bucketName, [
        'encryptionKey' => $oldBase64EncryptionKey,
        'destinationEncryptionKey' => $newBase64EncryptionKey,
    ]);

    printf('Rotated encryption key for object gs://%s/%s' . PHP_EOL,
        $bucketName, $objectName);
}

Python

For more information, see the Cloud Storage Python API reference documentation.

import base64

from google.cloud import storage


def rotate_encryption_key(
    bucket_name, blob_name, base64_encryption_key, base64_new_encryption_key
):
    """Performs a key rotation by re-writing an encrypted blob with a new
    encryption key."""
    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket_name)
    current_encryption_key = base64.b64decode(base64_encryption_key)
    new_encryption_key = base64.b64decode(base64_new_encryption_key)

    # Both source_blob and destination_blob refer to the same storage object,
    # but destination_blob has the new encryption key.
    source_blob = bucket.blob(
        blob_name, encryption_key=current_encryption_key
    )
    destination_blob = bucket.blob(
        blob_name, encryption_key=new_encryption_key
    )

    token = None

    while True:
        token, bytes_rewritten, total_bytes = destination_blob.rewrite(
            source_blob, token=token
        )
        if token is None:
            break

    print("Key rotation complete for Blob {}".format(blob_name))

Ruby

For more information, see the Cloud Storage Ruby API reference documentation.

def rotate_encryption_key bucket_name:, file_name:, current_encryption_key:, new_encryption_key:
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"

  # The ID of your GCS object
  # file_name = "your-file-name"

  # The Base64 encoded AES-256 encryption key originally used to encrypt the object.
  # See the documentation on Customer-Supplied Encryption keys for more info:
  # https://cloud.google.com/storage/docs/encryption/using-customer-supplied-keys
  # current_encryption_key = "TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g="

  # The new encryption key to use
  # new_encryption_key = "0mMWhFvQOdS4AmxRpo8SJxXn5MjFhbz7DkKBUdUIef8="

  require "google/cloud/storage"

  storage = Google::Cloud::Storage.new
  bucket  = storage.bucket bucket_name
  file    = bucket.file file_name, encryption_key: current_encryption_key

  file.rotate encryption_key:     current_encryption_key,
              new_encryption_key: new_encryption_key

  puts "The encryption key for #{file.name} in #{bucket.name} was rotated."
end

What's next

To search and filter code samples for other Google Cloud products, see the Google Cloud sample browser.