Use customer-supplied encryption keys Stay organized with collections Save and categorize content based on your preferences.
This page describes how to use your own encryption key, referred to as acustomer-supplied encryption key, with Cloud Storage. For other encryptionoptions in Cloud Storage, seeData Encryption Options.
Generate your own encryption key
There are many ways to generate aBase64-encoded AES-256encryption key. Here are several examples:
C++
For more information, see theCloud StorageC++ API reference documentation.
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries.
// Create a pseudo-random number generator (PRNG), this is included for// demonstration purposes only. You should consult your security team about// best practices to initialize PRNG. In particular, you should verify that// the C++ library and operating system provide enough entropy to meet the// security policies in your organization.// Use the Mersenne-Twister Engine in this example:// https://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine// Any C++ PRNG can be used below, the choice is arbitrary.usingGeneratorType=std::mt19937_64;// Create the default random device to fetch entropy.std::random_devicerd;// Compute how much entropy we need to initialize the GeneratorType:constexprautokRequiredEntropyWords=GeneratorType::state_size*(GeneratorType::word_size/std::numeric_limits<unsignedint>::digits);// Capture the entropy bits into a vector.std::vector<std::uint64_t>entropy(kRequiredEntropyWords);std::generate(entropy.begin(),entropy.end(),[&rd]{returnrd();});// Create the PRNG with the fetched entropy.std::seed_seqseed(entropy.begin(),entropy.end());// initialized with enough entropy such that the encryption keys are not// predictable. Note that the default constructor for all the generators in// the C++ standard library produce predictable keys.std::mt19937_64gen(seed);namespacegcs=::google::cloud::storage;gcs::EncryptionKeyDatadata=gcs::CreateKeyFromGenerator(gen);std::cout <<"Base64 encoded key = " <<data.key <<"\n" <<"Base64 encoded SHA256 of key = " <<data.sha256 <<"\n";C#
For more information, see theCloud StorageC# API reference documentation.
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries.
usingGoogle.Cloud.Storage.V1;usingSystem;publicclassGenerateEncryptionKeySample{publicstringGenerateEncryptionKey(){varencryptionKey=EncryptionKey.Generate().Base64Key;Console.WriteLine($"Generated Base64-encoded AES-256 encryption key: {encryptionKey}");returnencryptionKey;}}Go
For more information, see theCloud StorageGo API reference documentation.
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries.
import("crypto/rand""encoding/base64""fmt""io")// generateEncryptionKey generates a 256 bit (32 byte) AES encryption key and// prints the base64 representation.funcgenerateEncryptionKey(wio.Writer)error{// This is included for demonstration purposes. You should generate your own// key. Please remember that encryption keys should be handled with a// comprehensive security policy.key:=make([]byte,32)if_,err:=rand.Read(key);err!=nil{returnfmt.Errorf("rand.Read: %w",err)}encryptionKey:=base64.StdEncoding.EncodeToString(key)fmt.Fprintf(w,"Generated base64-encoded encryption key: %v\n",encryptionKey)returnnil}Java
For more information, see theCloud StorageJava API reference documentation.
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries.
importcom.google.common.io.BaseEncoding;importjava.security.SecureRandom;publicclassGenerateEncryptionKey{/** * Generates a 256 bit (32 byte) AES encryption key and prints the base64 representation. This is * included for demonstration purposes only. You should generate your own key, and consult your * security team about best practices. Please remember that encryption keys should be handled with * a comprehensive security policy. */publicstaticvoidgenerateEncryptionKey(){byte[]key=newbyte[32];newSecureRandom().nextBytes(key);StringencryptionKey=BaseEncoding.base64().encode(key);System.out.println("Generated Base64-encoded AES-256 encryption key: "+encryptionKey);}}Node.js
For more information, see theCloud StorageNode.js API reference documentation.
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries.
constcrypto=require('crypto');functiongenerateEncryptionKey(){/** * Generates a 256 bit (32 byte) AES encryption key and prints the base64 * representation. * * This is included for demonstration purposes. You should generate your own * key. Please remember that encryption keys should be handled with a * comprehensive security policy. */constbuffer=crypto.randomBytes(32);constencodedKey=buffer.toString('base64');console.log(`Base 64 encoded encryption key:${encodedKey}`);}generateEncryptionKey();PHP
For more information, see theCloud StoragePHP API reference documentation.
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries.
/** * Generate a base64 encoded encryption key for Google Cloud Storage. */function generate_encryption_key(): void{ $key = random_bytes(32); $encodedKey = base64_encode($key); printf('Your encryption key: %s' . PHP_EOL, $encodedKey);}Python
For more information, see theCloud StoragePython API reference documentation.
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries.
importbase64importosdefgenerate_encryption_key():"""Generates a 256 bit (32 byte) AES encryption key and prints the base64 representation. This is included for demonstration purposes. You should generate your own key. Please remember that encryption keys should be handled with a comprehensive security policy. """key=os.urandom(32)encoded_key=base64.b64encode(key).decode("utf-8")print(f"Base 64 encoded encryption key:{encoded_key}")Ruby
For more information, see theCloud StorageRuby API reference documentation.
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries.
defgenerate_encryption_key# Generates a 256 bit (32 byte) AES encryption key and prints the base64 representation.## This is included for demonstration purposes. You should generate your own key.# Please remember that encryption keys should be handled with a comprehensive security policy.require"base64"require"openssl"encryption_key=OpenSSL::Cipher.new("aes-256-cfb").encrypt.random_keyencoded_enc_key=Base64.encode64encryption_keyputs"Sample encryption key:#{encoded_enc_key}"endUpload with your encryption key
To use customer-supplied encryption keys to upload an object:
Console
The Google Cloud console cannot be used to upload an object with acustomer-supplied encryption key. Use the Google Cloud CLI or the clientlibraries instead.
Command line
Use thegcloud storage cp command with the--encryption-keyflag:
gcloud storage cpSOURCE_DATA gs://BUCKET_NAME/OBJECT_NAME --encryption-key=YOUR_ENCRYPTION_KEY
Where:
SOURCE_DATAis the source location of the datayou're encrypting. This can be any source location supported by thecpcommand. For example, a local file such asDesktop/dogs.pngor another Cloud Storage object such asgs://my-bucket/pets/old-dog.png.BUCKET_NAMEis the name of the destinationbucket for this copy command. For example,my-bucket.OBJECT_NAMEis the name of the final,encrypted object. For example,pets/new-dog.png.YOUR_ENCRYPTION_KEYis theAES-256 keythat you want to use for encrypting the uploaded object.
Client libraries
For more information, see theCloud StorageC++ API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageC# API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageGo API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageJava API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageNode.js API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StoragePHP API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StoragePython API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageRuby API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries.C++
namespacegcs=::google::cloud::storage;using::google::cloud::StatusOr;[](gcs::Clientclient,std::stringconst&bucket_name,std::stringconst&object_name,std::stringconst&base64_aes256_key){StatusOr<gcs::ObjectMetadata>object_metadata=client.InsertObject(bucket_name,object_name,"top secret",gcs::EncryptionKey::FromBase64Key(base64_aes256_key));if(!object_metadata)throwstd::move(object_metadata).status();std::cout <<"The object " <<object_metadata->name() <<" was created in bucket " <<object_metadata->bucket() <<"\nFull metadata: " <<*object_metadata <<"\n";}C#
usingGoogle.Cloud.Storage.V1;usingSystem;usingSystem.IO;publicclassUploadEncryptedFileSample{publicvoidUploadEncryptedFile(stringkey="3eFsTXPvqi3BpT2ipFCGirslh1Jgc6ikjoAu2oQ5JcI=",stringbucketName="your-unique-bucket-name",stringlocalPath="my-local-path/my-file-name",stringobjectName="my-file-name"){varstorage=StorageClient.Create();usingvarfileStream=File.OpenRead(localPath);storage.UploadObject(bucketName,objectName,null,fileStream,newUploadObjectOptions{EncryptionKey=EncryptionKey.Create(Convert.FromBase64String(key))});Console.WriteLine($"Uploaded {objectName}.");}}Go
import("context""fmt""io""time""cloud.google.com/go/storage")// uploadEncryptedFile writes an object using AES-256 encryption key.funcuploadEncryptedFile(wio.Writer,bucket,objectstring,secretKey[]byte)error{// bucket := "bucket-name"// object := "object-name"// secretKey := []byte("secret-key")ctx:=context.Background()client,err:=storage.NewClient(ctx)iferr!=nil{returnfmt.Errorf("storage.NewClient: %w",err)}deferclient.Close()ctx,cancel:=context.WithTimeout(ctx,time.Second*50)defercancel()o:=client.Bucket(bucket).Object(object)// Optional: set a generation-match precondition to avoid potential race// conditions and data corruptions. The request to upload is aborted if the// object's generation number does not match your precondition.// For an object that does not yet exist, set the DoesNotExist precondition.o=o.If(storage.Conditions{DoesNotExist:true})// If the live object already exists in your bucket, set instead a// generation-match precondition using the live object's generation number.// attrs, err := o.Attrs(ctx)// if err != nil {// return fmt.Errorf("object.Attrs: %w", err)// }// o = o.If(storage.Conditions{GenerationMatch: attrs.Generation})// Encrypt the object's contents.wc:=o.Key(secretKey).NewWriter(ctx)if_,err:=wc.Write([]byte("top secret"));err!=nil{returnfmt.Errorf("Writer.Write: %w",err)}iferr:=wc.Close();err!=nil{returnfmt.Errorf("Writer.Close: %w",err)}fmt.Fprintf(w,"Uploaded encrypted object %v.\n",object)returnnil}Java
importcom.google.cloud.storage.BlobId;importcom.google.cloud.storage.BlobInfo;importcom.google.cloud.storage.Storage;importcom.google.cloud.storage.StorageOptions;importjava.io.IOException;importjava.nio.file.Files;importjava.nio.file.Paths;publicclassUploadEncryptedObject{publicstaticvoiduploadEncryptedObject(StringprojectId,StringbucketName,StringobjectName,StringfilePath,StringencryptionKey)throwsIOException{// 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 path to your file to upload// String filePath = "path/to/your/file"// The key to encrypt the object with// String encryptionKey = "TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=";Storagestorage=StorageOptions.newBuilder().setProjectId(projectId).build().getService();BlobIdblobId=BlobId.of(bucketName,objectName);BlobInfoblobInfo=BlobInfo.newBuilder(blobId).build();// Optional: set a generation-match precondition to avoid potential race// conditions and data corruptions. The request returns a 412 error if the// preconditions are not met.Storage.BlobTargetOptionprecondition;if(storage.get(bucketName,objectName)==null){// For a target object that does not yet exist, set the DoesNotExist precondition.// This will cause the request to fail if the object is created before the request runs.precondition=Storage.BlobTargetOption.doesNotExist();}else{// If the destination already exists in your bucket, instead set a generation-match// precondition. This will cause the request to fail if the existing object's generation// changes before the request runs.precondition=Storage.BlobTargetOption.generationMatch(storage.get(bucketName,objectName).getGeneration());}storage.create(blobInfo,Files.readAllBytes(Paths.get(filePath)),Storage.BlobTargetOption.encryptionKey(encryptionKey),precondition);System.out.println("File "+filePath+" uploaded to bucket "+bucketName+" as "+objectName+" with supplied encryption key");}}Node.js
/** * TODO(developer): Uncomment the following lines before running the sample. */// The ID of your GCS bucket// const bucketName = 'your-unique-bucket-name';// The path to your file to upload// const filePath = 'path/to/your/file';// The new ID for your GCS file// const destFileName = 'your-new-file-name';// The key to encrypt the object with// const key = 'TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=';// Imports the Google Cloud client libraryconst{Storage}=require('@google-cloud/storage');// Creates a clientconststorage=newStorage();asyncfunctionuploadEncryptedFile(){constoptions={destination:destFileName,encryptionKey:Buffer.from(key,'base64'),// Optional:// Set a generation-match precondition to avoid potential race conditions// and data corruptions. The request to upload is aborted if the object's// generation number does not match your precondition. For a destination// object that does not yet exist, set the ifGenerationMatch precondition to 0// If the destination object already exists in your bucket, set instead a// generation-match precondition using its generation number.preconditionOpts:{ifGenerationMatch:generationMatchPrecondition},};awaitstorage.bucket(bucketName).upload(filePath,options);console.log(`File${filePath} uploaded to gs://${bucketName}/${destFileName}`);}uploadEncryptedFile().catch(console.error);PHP
use Google\Cloud\Storage\StorageClient;/** * Upload an encrypted file. * * @param string $bucketName The name of your Cloud Storage bucket. * (e.g. 'my-bucket') * @param string $objectName The name of your Cloud Storage object. * (e.g. 'my-object') * @param string $source The path to the file to upload. * (e.g. '/path/to/your/file') * @param string $base64EncryptionKey The base64 encoded encryption key. * (e.g. 'TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=') */function upload_encrypted_object(string $bucketName, string $objectName, string $source, string $base64EncryptionKey): void{ $storage = new StorageClient(); $file = fopen($source, 'r'); $bucket = $storage->bucket($bucketName); $object = $bucket->upload($file, [ 'name' => $objectName, 'encryptionKey' => $base64EncryptionKey, ]); printf('Uploaded encrypted %s to gs://%s/%s' . PHP_EOL, basename($source), $bucketName, $objectName);}Python
importbase64fromgoogle.cloudimportstoragedefupload_encrypted_blob(bucket_name,source_file_name,destination_blob_name,base64_encryption_key,):"""Uploads a file to a Google Cloud Storage bucket using a custom encryption key. The file will be encrypted by Google Cloud Storage and only retrievable using the provided encryption key. """# bucket_name = "your-bucket-name"# source_file_name = "local/path/to/file"# destination_blob_name = "storage-object-name"# base64_encryption_key = "TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g="storage_client=storage.Client()bucket=storage_client.bucket(bucket_name)# Encryption key must be an AES256 key represented as a bytestring with# 32 bytes. Since it's passed in as a base64 encoded string, it needs# to be decoded.encryption_key=base64.b64decode(base64_encryption_key)blob=bucket.blob(destination_blob_name,encryption_key=encryption_key)# Optional: set a generation-match precondition to avoid potential race conditions# and data corruptions. The request to upload is aborted if the object's# generation number does not match your precondition. For a destination# object that does not yet exist, set the if_generation_match precondition to 0.# If the destination object already exists in your bucket, set instead a# generation-match precondition using its generation number.generation_match_precondition=0blob.upload_from_filename(source_file_name,if_generation_match=generation_match_precondition)print(f"File{source_file_name} uploaded to{destination_blob_name}.")Ruby
defupload_encrypted_filebucket_name:,local_file_path:,file_name:nil,encryption_key:# The ID of your GCS bucket# bucket_name = "your-unique-bucket-name"# The path to your file to upload# local_file_path = "/local/path/to/file.txt"# The ID of your GCS object# file_name = "your-file-name"# The encryption key used for securing the object must be a 32-byte key consisting of raw encrypted data.# Key used should not be base64 encoded.# encryption_key = "your-encryption-key"require"google/cloud/storage"storage=Google::Cloud::Storage.newbucket=storage.bucketbucket_name,skip_lookup:truefile=bucket.create_filelocal_file_path,file_name,encryption_key:encryption_keyputs"Uploaded#{file.name} with encryption key"end
REST APIs
JSON API
Have gcloud CLIinstalled and initialized, which lets you generate an access token for the
Authorizationheader.Use
cURLto call theJSON API with aPOSTObject request:curl -X POST --data-binary @OBJECT \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type:OBJECT_CONTENT_TYPE" \ -H "x-goog-encryption-algorithm: AES256" \ -H "x-goog-encryption-key:YOUR_ENCRYPTION_KEY" \ -H "x-goog-encryption-key-sha256:HASH_OF_YOUR_KEY" \ "https://storage.googleapis.com/upload/storage/v1/b/BUCKET_NAME/o?uploadType=media&name=OBJECT_NAME"
Where:
OBJECTis the path to the object you areuploading. For example,Desktop/dogs.png.OBJECT_CONTENT_TYPEis thecontent type of the object. For example,image/png.YOUR_ENCRYPTION_KEYis theAES-256 key used for encrypting the uploaded object.HASH_OF_YOUR_KEYis the SHA-256 hash foryour AES-256 key.BUCKET_NAMEis the name of the bucket towhich you are uploading the object. For example,my-bucket.OBJECT_NAMEis the URL-encoded name of theobject you are uploading. For example,pets/dog.png,URL-encoded aspets%2Fdog.png.
SeeEncryption request headers for more information onencryption-specific headers.
XML API
Have gcloud CLIinstalled and initialized, which lets you generate an access token for the
Authorizationheader.Use
cURLto call theXML API with aPUTOBJECT request:curl -X -i PUT --data-binary @OBJECT \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type:OBJECT_CONTENT_TYPE" \ -H "x-goog-encryption-algorithm: AES256" \ -H "x-goog-encryption-key:YOUR_ENCRYPTION_KEY" \ -H "x-goog-encryption-key-sha256:HASH_OF_YOUR_KEY" \ "https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME"
Where:
OBJECTis the path to the object you areuploading. For example,Desktop/dogs.png.OBJECT_CONTENT_TYPEis thecontent type of the object. For example,image/png.YOUR_ENCRYPTION_KEYis theAES-256 key used for encrypting the uploaded object.HASH_OF_YOUR_KEYis the SHA-256 hash foryour AES-256 key.BUCKET_NAMEis the name of the bucket towhich you are uploading the object. For example,my-bucket.OBJECT_NAMEis the URL-encoded name of theobject you are uploading. For example,pets/dog.png,URL-encoded aspets%2Fdog.png.
SeeEncryption request headers for more information onencryption-specific headers.
Download objects you've encrypted
To download an object stored in Cloud Storage that is encrypted with acustomer-supplied encryption key:
Console
The Google Cloud console cannot be used to download objects encrypted withcustomer-supplied encryption keys. Use the Google Cloud CLI or the clientlibraries instead.
Command line
Use thegcloud storage cp command with the--decryption-keysflag:
gcloud storage cp gs://BUCKET_NAME/OBJECT_NAMEOBJECT_DESTINATION --decryption-keys=YOUR_ENCRYPTION_KEY
Where:
BUCKET_NAMEis the name of the bucketcontaining the object you are downloading. For example,my-bucket.OBJECT_NAMEis the name of the object youare downloading. For example,pets/dog.png.OBJECT_DESTINATIONis the location where youwant to save your object. For example,Desktop.YOUR_ENCRYPTION_KEYis theAES-256 keyused to encrypt the object when it was uploaded.
Client libraries
For more information, see theCloud StorageC++ API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageC# API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageGo API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageJava API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageNode.js API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StoragePHP API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StoragePython API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageRuby API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries.C++
namespacegcs=::google::cloud::storage;[](gcs::Clientclient,std::stringconst&bucket_name,std::stringconst&object_name,std::stringconst&base64_aes256_key){gcs::ObjectReadStreamstream=client.ReadObject(bucket_name,object_name,gcs::EncryptionKey::FromBase64Key(base64_aes256_key));std::stringdata(std::istreambuf_iterator<char>{stream},{});if(stream.bad())throwgoogle::cloud::Status(stream.status());std::cout <<"The object contents are: " <<data <<"\n";}C#
usingGoogle.Cloud.Storage.V1;usingSystem;usingSystem.IO;publicclassDownloadEncryptedFileSample{publicvoidDownloadEncryptedFile(stringkey="3eFsTXPvqi3BpT2ipFCGirslh1Jgc6ikjoAu2oQ5JcI=",stringbucketName="your-unique-bucket-name",stringobjectName="my-file-name",stringlocalPath="my-local-path/my-file-name"){varstorage=StorageClient.Create();usingvaroutputFile=File.OpenWrite(localPath);storage.DownloadObject(bucketName,objectName,outputFile,newDownloadObjectOptions{EncryptionKey=EncryptionKey.Create(Convert.FromBase64String(key))});Console.WriteLine($"Downloaded {objectName} to {localPath}.");}}Go
import("context""fmt""io""time""cloud.google.com/go/storage")// downloadEncryptedFile reads an encrypted object.funcdownloadEncryptedFile(wio.Writer,bucket,objectstring,secretKey[]byte)([]byte,error){// bucket := "bucket-name"// object := "object-name"// key := []byte("secret-encryption-key")ctx:=context.Background()client,err:=storage.NewClient(ctx)iferr!=nil{returnnil,fmt.Errorf("storage.NewClient: %w",err)}deferclient.Close()obj:=client.Bucket(bucket).Object(object)ctx,cancel:=context.WithTimeout(ctx,time.Second*50)defercancel()rc,err:=obj.Key(secretKey).NewReader(ctx)iferr!=nil{returnnil,fmt.Errorf("Object(%q).Key(%q).NewReader: %w",object,secretKey,err)}deferrc.Close()data,err:=io.ReadAll(rc)iferr!=nil{returnnil,fmt.Errorf("io.ReadAll: %w",err)}fmt.Fprintf(w,"File %v downloaded with encryption key.\n",object)returndata,nil}Java
importcom.google.cloud.storage.Blob;importcom.google.cloud.storage.Storage;importcom.google.cloud.storage.StorageOptions;importjava.io.IOException;importjava.nio.file.Path;publicclassDownloadEncryptedObject{publicstaticvoiddownloadEncryptedObject(StringprojectId,StringbucketName,StringobjectName,PathdestFilePath,StringdecryptionKey)throwsIOException{// 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 path to which the file should be downloaded// Path destFilePath = Paths.get("/local/path/to/file.txt");// The Base64 encoded decryption key, which should be the same key originally used to encrypt// the object// String decryptionKey = "TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=";Storagestorage=StorageOptions.newBuilder().setProjectId(projectId).build().getService();Blobblob=storage.get(bucketName,objectName);blob.downloadTo(destFilePath,Blob.BlobSourceOption.decryptionKey(decryptionKey));System.out.println("Downloaded object "+objectName+" from bucket name "+bucketName+" to "+destFilePath+" using customer-supplied encryption key");}}Node.js
/** * 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 srcFileName = 'your-file-name';// The path to which the file should be downloaded// const destFileName = '/local/path/to/file.txt';// The Base64 encoded decryption key, which should be the same key originally// used to encrypt the file// const encryptionKey = 'TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=';// Imports the Google Cloud client libraryconst{Storage}=require('@google-cloud/storage');// Creates a clientconststorage=newStorage();asyncfunctiondownloadEncryptedFile(){constoptions={destination:destFileName,};// Decrypts and downloads the file. This can only be done with the key used// to encrypt and upload the file.awaitstorage.bucket(bucketName).file(srcFileName).setEncryptionKey(Buffer.from(encryptionKey,'base64')).download(options);console.log(`File${srcFileName} downloaded to${destFileName}`);}downloadEncryptedFile().catch(console.error);PHP
use Google\Cloud\Storage\StorageClient;/** * Download an encrypted file * * @param string $bucketName The name of your Cloud Storage bucket. * (e.g. 'my-bucket') * @param string $objectName The name of your Cloud Storage object. * (e.g. 'my-object') * @param string $destination The local destination to save the encrypted file. * (e.g. '/path/to/your/file') * @param string $base64EncryptionKey The base64 encoded encryption key. Should * (e.g. 'TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=') * be the same key originally used to encrypt the object. */function download_encrypted_object(string $bucketName, string $objectName, string $destination, string $base64EncryptionKey): void{ $storage = new StorageClient(); $bucket = $storage->bucket($bucketName); $object = $bucket->object($objectName); $object->downloadToFile($destination, [ 'encryptionKey' => $base64EncryptionKey, ]); printf('Encrypted object gs://%s/%s downloaded to %s' . PHP_EOL, $bucketName, $objectName, basename($destination));}Python
importbase64fromgoogle.cloudimportstoragedefdownload_encrypted_blob(bucket_name,source_blob_name,destination_file_name,base64_encryption_key,):"""Downloads a previously-encrypted blob from Google Cloud Storage. The encryption key provided must be the same key provided when uploading the blob. """# bucket_name = "your-bucket-name"# source_blob_name = "storage-object-name"# destination_file_name = "local/path/to/file"# base64_encryption_key = "base64-encoded-encryption-key"storage_client=storage.Client()bucket=storage_client.bucket(bucket_name)# Encryption key must be an AES256 key represented as a bytestring with# 32 bytes. Since it's passed in as a base64 encoded string, it needs# to be decoded.encryption_key=base64.b64decode(base64_encryption_key)blob=bucket.blob(source_blob_name,encryption_key=encryption_key)blob.download_to_filename(destination_file_name)print(f"Blob{source_blob_name} downloaded to{destination_file_name}.")Ruby
defdownload_encrypted_filebucket_name:,file_name:,local_file_path:,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 path to which the file should be downloaded# local_file_path = "/local/path/to/file.txt"# The Base64 encoded decryption key, which should be the same key originally used to encrypt the object# encryption_key = "TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g="require"google/cloud/storage"storage=Google::Cloud::Storage.newbucket=storage.bucketbucket_name,skip_lookup:truefile=bucket.filefile_name,encryption_key:encryption_keyfile.downloadlocal_file_path,encryption_key:encryption_keyputs"Downloaded encrypted#{file.name} to#{local_file_path}"end
REST APIs
JSON API
Have gcloud CLIinstalled and initialized, which lets you generate an access token for the
Authorizationheader.Use
cURLto call theJSON API with aGETObject request:curl -X GET \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "x-goog-encryption-algorithm: AES256" \ -H "x-goog-encryption-key:YOUR_ENCRYPTION_KEY" \ -H "x-goog-encryption-key-sha256:HASH_OF_YOUR_KEY" \ -o "SAVE_TO_LOCATION" \ "https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME?alt=media"
Where:
YOUR_ENCRYPTION_KEYis theAES-256 key you used to encrypt the object.HASH_OF_YOUR_KEYis the SHA-256 hash foryour AES-256 key.SAVE_TO_LOCATIONis the location whereyou want to save your object. For example,Desktop/dog.png.BUCKET_NAMEis the name of the bucket fromwhich you are downloading the object. For example,my-bucket.OBJECT_NAMEis the URL-encoded name of theobject you are downloading. For example,pets/dog.png,URL-encoded aspets%2Fdog.png.
SeeEncryption request headers for more information onencryption-specific headers.
XML API
Have gcloud CLIinstalled and initialized, which lets you generate an access token for the
Authorizationheader.Use
cURLto call theXML API with aGETOBJECT request:curl -X GET \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "x-goog-encryption-algorithm: AES256" \ -H "x-goog-encryption-key:YOUR_ENCRYPTION_KEY" \ -H "x-goog-encryption-key-sha256:HASH_OF_YOUR_KEY" \ -o "SAVE_TO_LOCATION" \ "https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME"
Where:
YOUR_ENCRYPTION_KEYis theAES-256 key you used to encrypt the object.HASH_OF_YOUR_KEYis the SHA-256 hash foryour AES-256 key.SAVE_TO_LOCATIONis the location whereyou want to save your object. For example,Desktop/dog.png.BUCKET_NAMEis the name of the bucket fromwhich you are downloading the object. For example,my-bucket.OBJECT_NAMEis the URL-encoded name of theobject you are downloading. For example,pets/dog.png,URL-encoded aspets%2Fdog.png.
SeeEncryption request headers for more information onencryption-specific headers.
Rotate your encryption keys
To rotate a customer-supplied encryption key:
Console
The Google Cloud console cannot be used to rotate customer-suppliedencryption keys. Use the Google Cloud CLI or the client libraries instead.
Command line
Use thegcloud storage objects update command with theappropriate flags:
gcloud storage objects update gs://BUCKET_NAME/OBJECT_NAME --encryption-key=NEW_KEY --decryption-keys=OLD_KEY
Where:
BUCKET_NAMEis the name of the bucket thatcontains the object whose key you are rotating. For example,my-bucket.OBJECT_NAMEis the name of the object whosekey you are rotating. For example,pets/dog.png.NEW_KEYis the new customer-suppliedencryption key that you want to use to encrypt the object.OLD_KEYis the current customer-suppliedencryption key that is used to encrypt the object.
Client libraries
For more information, see theCloud StorageC++ API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageC# API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageGo API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageJava API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageNode.js API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StoragePHP API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StoragePython API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries. For more information, see theCloud StorageRuby API reference documentation. To authenticate to Cloud Storage, set up Application Default Credentials. For more information, seeSet up authentication for client libraries.C++
namespacegcs=::google::cloud::storage;using::google::cloud::StatusOr;[](gcs::Clientclient,std::stringconst&bucket_name,std::stringconst&object_name,std::stringconst&old_key_base64,std::stringconst&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)throwstd::move(object_metadata).status();std::cout <<"Rotated key on object " <<object_metadata->name() <<" in bucket " <<object_metadata->bucket() <<"\nFull Metadata: " <<*object_metadata <<"\n";}C#
usingGoogle.Cloud.Storage.V1;usingSystem;usingSystem.IO;publicclassObjectRotateEncryptionKeySample{publicvoidObjectRotateEncryptionKey(stringbucketName="your-unique-bucket-name",stringobjectName="your-object-name",stringcurrrentEncryptionKey="TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=",stringnewEncryptionKey="ARbt/judaq+VmtXzAsc83J4z5kFmWJ6NdAPQuleuB7g="){varstorage=StorageClient.Create();usingvaroutputStream=newMemoryStream();storage.DownloadObject(bucketName,objectName,outputStream,newDownloadObjectOptions(){EncryptionKey=EncryptionKey.Create(Convert.FromBase64String(currrentEncryptionKey))});outputStream.Position=0;storage.UploadObject(bucketName,objectName,null,outputStream,newUploadObjectOptions(){EncryptionKey=EncryptionKey.Create(Convert.FromBase64String(newEncryptionKey))});Console.WriteLine($"Rotated encryption key for object {objectName} in bucket {bucketName}");}}Go
import("context""fmt""io""time""cloud.google.com/go/storage")// rotateEncryptionKey encrypts an object with the newKey.funcrotateEncryptionKey(wio.Writer,bucket,objectstring,key,newKey[]byte)error{// bucket := "bucket-name"// object := "object-name"// key := []byte("encryption-key")// newKey := []byte("new-encryption-key")ctx:=context.Background()client,err:=storage.NewClient(ctx)iferr!=nil{returnfmt.Errorf("storage.NewClient: %w",err)}deferclient.Close()ctx,cancel:=context.WithTimeout(ctx,time.Second*10)defercancel()o:=client.Bucket(bucket).Object(object)// Optional: set a generation-match precondition to avoid potential race// conditions and data corruptions. The request to copy is aborted if the// object's generation number does not match your precondition.attrs,err:=o.Attrs(ctx)iferr!=nil{returnfmt.Errorf("object.Attrs: %w",err)}o=o.If(storage.Conditions{GenerationMatch:attrs.Generation})// You can't change an object's encryption key directly, you must rewrite the// object using the new key._,err=o.Key(newKey).CopierFrom(o.Key(key)).Run(ctx)iferr!=nil{returnfmt.Errorf("Key(%q).CopierFrom(%q).Run: %w",newKey,key,err)}fmt.Fprintf(w,"Key rotation complete for blob %v.\n",object)returnnil}Java
importcom.google.cloud.storage.Blob;importcom.google.cloud.storage.BlobId;importcom.google.cloud.storage.Storage;importcom.google.cloud.storage.StorageOptions;publicclassRotateObjectEncryptionKey{publicstaticvoidrotateObjectEncryptionKey(StringprojectId,StringbucketName,StringobjectName,StringoldEncryptionKey,StringnewEncryptionKey){// 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="Storagestorage=StorageOptions.newBuilder().setProjectId(projectId).build().getService();BlobIdblobId=BlobId.of(bucketName,objectName);Blobblob=storage.get(blobId);if(blob==null){System.out.println("The object "+objectName+" wasn't found in "+bucketName);return;}// Optional: set a generation-match precondition to avoid potential race// conditions and data corruptions. The request to upload returns a 412 error if// the object's generation number does not match your precondition.Storage.BlobSourceOptionprecondition=Storage.BlobSourceOption.generationMatch(blob.getGeneration());// You can't change an object's encryption key directly, the only way is to overwrite the objectStorage.CopyRequestrequest=Storage.CopyRequest.newBuilder().setSource(blobId).setSourceOptions(Storage.BlobSourceOption.decryptionKey(oldEncryptionKey),precondition).setTarget(blobId,Storage.BlobTargetOption.encryptionKey(newEncryptionKey)).build();storage.copy(request);System.out.println("Rotated encryption key for object "+objectName+"in bucket "+bucketName);}}Node.js
/** * 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 libraryconst{Storage}=require('@google-cloud/storage');// Creates a clientconststorage=newStorage();asyncfunctionrotateEncryptionKey(){constrotateEncryptionKeyOptions={encryptionKey:Buffer.from(newKey,'base64'),// Optional: set a generation-match precondition to avoid potential race// conditions and data corruptions. The request to copy is aborted if the// object's generation number does not match your precondition.preconditionOpts:{ifGenerationMatch:generationMatchPrecondition,},};awaitstorage.bucket(bucketName).file(fileName,{encryptionKey:Buffer.from(oldKey,'base64'),}).rotateEncryptionKey({rotateEncryptionKeyOptions,});console.log('Encryption key rotated successfully');}rotateEncryptionKey().catch(console.error);PHP
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. * (e.g. 'my-bucket') * @param string $objectName The name of your Cloud Storage object. * (e.g. 'my-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 * (e.g. 'TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=') * @param string $newBase64EncryptionKey The new base64 encoded encryption key. * (e.g. '0mMWhFvQOdS4AmxRpo8SJxXn5MjFhbz7DkKBUdUIef8=') */function rotate_encryption_key( string $bucketName, string $objectName, string $oldBase64EncryptionKey, string $newBase64EncryptionKey): void { $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
importbase64fromgoogle.cloudimportstoragedefrotate_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)generation_match_precondition=Nonetoken=None# Optional: set a generation-match precondition to avoid potential race conditions# and data corruptions. The request to rewrite is aborted if the object's# generation number does not match your precondition.source_blob.reload()# Fetch blob metadata to use in generation_match_precondition.generation_match_precondition=source_blob.generationwhileTrue:token,bytes_rewritten,total_bytes=destination_blob.rewrite(source_blob,token=token,if_generation_match=generation_match_precondition)iftokenisNone:breakprint(f"Key rotation complete for Blob{blob_name}")Ruby
defrotate_encryption_keybucket_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.newbucket=storage.bucketbucket_name,skip_lookup:truefile=bucket.filefile_name,encryption_key:current_encryption_keyfile.rotateencryption_key:current_encryption_key,new_encryption_key:new_encryption_keyputs"The encryption key for#{file.name} in#{bucket.name} was rotated."end
REST APIs
JSON API
Have gcloud CLIinstalled and initialized, which lets you generate an access token for the
Authorizationheader.Use
cURLto call theJSON API with aPOSTObject request:curl -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Length: 0" \ -H "x-goog-encryption-algorithm: AES256" \ -H "x-goog-encryption-key:NEW_ENCRYPTION_KEY" \ -H "x-goog-encryption-key-sha256:HASH_OF_NEW_KEY" \ -H "x-goog-copy-source-encryption-algorithm: AES256" \ -H "x-goog-copy-source-encryption-key:OLD_ENCRYPTION_KEY" \ -H "x-goog-copy-source-encryption-key-sha256:HASH_OF_OLD_KEY" \ "https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME/rewriteTo/b/BUCKET_NAME/o/OBJECT_NAME"
Where:
NEW_ENCRYPTION_KEYis the new AES-256 keyused for encrypting your object.HASH_OF_NEW_KEYis the SHA-256 hash foryour new AES-256 key.OLD_ENCRYPTION_KEYis the current AES-256key used to encrypt your object.HASH_OF_OLD_KEYis the current SHA-256hash for your AES-256 key.BUCKET_NAMEis the name of the bucketcontaining the relevant object. For example,my-bucket.OBJECT_NAMEis the URL-encoded name of theobject whose keys you are rotating. For example,pets/dog.png,URL-encoded aspets%2Fdog.png.
SeeEncryption request headers for more information onencryption-specific headers.
XML API
The XML API does not support rotating a customer-supplied encryptionkey through rewriting object. To apply a new customer-supplied key to anobject using the XML API, you should:
What's next
Learn more aboutcustomer-supplied encryption keys.
Learn how torotate your customer-supplied encryption key to aCloud KMS key
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-17 UTC.