Sample converts CSEK to CMEK.
Explore further
For detailed documentation that includes this code sample, see the following:
Code sample
C++
For more information, see the Cloud Storage C++ API reference documentation .
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for client libraries .
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_csek_key_base64
,
std
::
string
const
&
new_cmek_key_name
)
{
StatusOr<gcs
::
ObjectMetadata
>
metadata
=
client
.
RewriteObjectBlocking
(
bucket_name
,
object_name
,
bucket_name
,
object_name
,
gcs
::
SourceEncryptionKey
::
FromBase64Key
(
old_csek_key_base64
),
gcs
::
DestinationKmsKeyName
(
new_cmek_key_name
));
if
(
!
metadata
)
throw
std
::
move
(
metadata
).
status
();
std
::
cout
<<
"Changed object "
<<
metadata
-
> name
()
<<
" in bucket "
<<
metadata
-
> bucket
()
<<
" from using CSEK to CMEK key.
\n
Full Metadata: "
<<
*
metadata
<<
"
\n
"
;
}
C#
For more information, see the Cloud Storage C# API reference documentation .
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for client libraries .
using
Google.Cloud.Storage.V1
;
using
System
;
using
System.IO
;
public
class
ObjectCsekToCmekSample
{
public
void
ObjectCsekToCmek
(
string
projectId
=
"your-project-id"
,
string
bucketName
=
"your-unique-bucket-name"
,
string
objectName
=
"your-object-name"
,
string
currrentEncryptionKey
=
"TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g="
,
string
keyLocation
=
"us-west1"
,
string
kmsKeyRing
=
"kms-key-ring"
,
string
kmsKeyName
=
"key-name"
)
{
string
keyPrefix
=
$"projects/{projectId}/locations/{keyLocation}"
;
string
fullKeyringName
=
$"{keyPrefix}/keyRings/{kmsKeyRing}"
;
string
fullKeyName
=
$"{fullKeyringName}/cryptoKeys/{kmsKeyName}"
;
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
()
{
KmsKeyName
=
fullKeyName
});
Console
.
WriteLine
(
$"Object {objectName} in bucket {bucketName} is now managed"
+
$" by the KMS key ${kmsKeyName} instead of a customer-supplied encryption key"
);
}
}
Go
For more information, see the Cloud Storage Go API reference documentation .
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for client libraries .
import
(
"context"
"fmt"
"io"
"time"
"cloud.google.com/go/storage"
)
// сhangeObjectCSEKtoKMS changes the key used to encrypt an object from
// a customer-supplied encryption key to a customer-managed encryption key.
func
сhangeObjectCSEKToKMS
(
w
io
.
Wr Writer
bucket
,
object
string
,
encryptionKey
[]
byte
,
kmsKeyName
string
)
error
{
// bucket := "bucket-name"
// object := "object-name"
// encryptionKey is the Base64 encoded decryption key, which should be the same
// key originally used to encrypt the object.
// encryptionKey := []byte("TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=")
// kmsKeyName is the name of the KMS key to manage this object with.
// kmsKeyName := "projects/projectId/locations/global/keyRings/keyRingID/cryptoKeys/cryptoKeyID"
ctx
:=
context
.
Background
()
client
,
err
:=
storage
.
NewClient
(
ctx
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"storage.NewClient: %w"
,
err
)
}
defer
client
.
Close
()
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
time
.
Second
*
10
)
defer
cancel
()
o
:=
clclient
.
Bucket
(
bucket
).
Object
bject )
// 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
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"object.Attrs: %w"
,
err
)
}
o
=
o
.
If
(
storage
.
Co Conditions
enerationMatch
:
atattrs
.
Generation
// You can't change an object's encryption key directly. Instead, you must
// rewrite the object using the new key.
src
:=
o
.
o
.
Key
ncryptionKey )
c
:=
o
.
o
.
CopierFrom
rc )
c
.
DestinationKMSKeyName
=
kmsKeyName
if
_
,
err
:=
c
.
Run
(
ctx
);
err
!=
nil
{
return
fmt
.
Errorf
(
"Copier.Run: %w"
,
err
)
}
fmt
.
Fprintf
(
w
,
"Object %v in bucket %v is now managed by the KMS key %v instead of a customer-supplied encryption key\n"
,
object
,
bucket
,
kmsKeyName
)
return
nil
}
Java
For more information, see the Cloud Storage Java API reference documentation .
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for client libraries .
import
com.google.cloud.storage. Blob
;
import
com.google.cloud.storage. BlobId
;
import
com.google.cloud.storage. Storage
;
import
com.google.cloud.storage. StorageOptions
;
public
class
ChangeObjectCsekToKms
{
public
static
void
changeObjectFromCsekToKms
(
String
projectId
,
String
bucketName
,
String
objectName
,
String
decryptionKey
,
String
kmsKeyName
)
{
// 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 decryption key, which should be the same key originally used to encrypt
// the object
// String decryptionKey = "TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=";
// The name of the KMS key to manage this object with
// String kmsKeyName =
// "projects/your-project-id/locations/global/keyRings/your-key-ring/cryptoKeys/your-key";
Storage
storage
=
StorageOptions
.
newBuilder
().
setProjectId
(
projectId
).
build
().
getService
();
BlobId
blobId
=
BlobId
.
of
(
bucketName
,
objectName
);
Blob
blob
=
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
.
BlobSourceOption
precondition
=
Storage
.
BlobSourceOption
.
generationMatch
(
blob
.
getGeneration
());
Storage
.
CopyRequest
request
=
Storage
.
CopyRequest
.
newBuilder
()
.
setSource
(
blobId
)
.
setSourceOptions
(
Storage
.
BlobSourceOption
.
decryptionKey
(
decryptionKey
),
precondition
)
.
setTarget
(
blobId
,
Storage
.
BlobTargetOption
.
kmsKeyName
(
kmsKeyName
))
.
build
();
storage
.
copy
(
request
);
System
.
out
.
println
(
"Object "
+
objectName
+
" in bucket "
+
bucketName
+
" is now managed by the KMS key "
+
kmsKeyName
+
" instead of a customer-supplied encryption key"
);
}
}
Node.js
For more information, see the Cloud Storage Node.js API reference documentation .
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for client libraries .
/**
* 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 decryption key, which should be the same key originally
// used to encrypt the file
// const encryptionKey = 'TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=';
// The name of the KMS key to manage this file with
// const kmsKeyName = 'projects/your-project-id/locations/global/keyRings/your-key-ring/cryptoKeys/your-key';
// Imports the Google Cloud client library
const
{
Storage
}
=
require
(
' @google-cloud/storage
'
);
// Creates a client
const
storage
=
new
Storage
();
async
function
changeFileCSEKToCMEK
()
{
const
rotateEncryptionKeyOptions
=
{
kmsKeyName
,
// 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
,
},
};
console
.
log
(
rotateEncryptionKeyOptions
);
await
storage
.
bucket
(
bucketName
)
.
file
(
fileName
,
{
encryptionKey
:
Buffer
.
from
(
encryptionKey
,
' base64
'
),
})
.
rotateEncryptionKey
({
rotateEncryptionKeyOptions
,
});
console
.
log
(
`file
${
fileName
}
in bucket
${
bucketName
}
is now managed by KMS key
${
kmsKeyName
}
instead of customer-supplied encryption key`
);
}
changeFileCSEKToCMEK
().
catch
(
console
.
error
);
PHP
For more information, see the Cloud Storage PHP API reference documentation .
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for client libraries .
use Google\Cloud\Storage\StorageClient;
/**
* Migrate an object from a Customer-Specified Encryption Key to a Customer-Managed
* Encryption Key.
*
* @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 $decryptionKey The Base64 encoded decryption key, which should
* (e.g. 'TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=')
* be the same key originally used to encrypt the object.
* @param string $kmsKeyName The name of the KMS key to manage this object.
* Key names are provided in the following format:
* `projects/<PROJECT>/locations/<LOCATION>/keyRings/<RING_NAME>/cryptoKeys/<KEY_NAME>`.
*/
function object_csek_to_cmek(string $bucketName, string $objectName, string $decryptionKey, string $kmsKeyName): void
{
$storage = new StorageClient();
$bucket = $storage->bucket($bucketName);
$object = $bucket->object($objectName, [
'encryptionKey' => $decryptionKey,
]);
$object->rewrite($bucketName, [
'destinationKmsKeyName' => $kmsKeyName,
]);
printf(
'Object %s in bucket %s is now managed by the KMS key %s instead of a customer-supplied encryption key',
$objectName,
$bucketName,
$kmsKeyName
);
}
Python
For more information, see the Cloud Storage Python API reference documentation .
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for client libraries .
from
google.cloud
import
storage
def
object_csek_to_cmek
(
bucket_name
,
blob_name
,
encryption_key
,
kms_key_name
):
"""Change a blob's customer-supplied encryption key to KMS key"""
# bucket_name = "your-bucket-name"
# blob_name = "your-object-name"
# encryption_key = "TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g="
# kms_key_name = "projects/PROJ/locations/LOC/keyRings/RING/cryptoKey/KEY"
storage_client
=
storage
.
Client
()
bucket
=
storage_client
.
bucket
(
bucket_name
)
current_encryption_key
=
base64
.
b64decode
(
encryption_key
)
source_blob
=
bucket
.
blob
(
blob_name
,
encryption_key
=
current_encryption_key
)
destination_blob
=
bucket
.
blob
(
blob_name
,
kms_key_name
=
kms_key_name
)
generation_match_precondition
=
None
token
=
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
.
generation
while
True
:
token
,
bytes_rewritten
,
total_bytes
=
destination_blob
.
rewrite
(
source_blob
,
token
=
token
,
if_generation_match
=
generation_match_precondition
)
if
token
is
None
:
break
print
(
"Blob
{}
in bucket
{}
is now managed by the KMS key
{}
instead of a customer-supplied encryption key"
.
format
(
blob_name
,
bucket_name
,
kms_key_name
)
)
return
destination_blob
Ruby
For more information, see the Cloud Storage Ruby API reference documentation .
To authenticate to Cloud Storage, set up Application Default Credentials. For more information, see Set up authentication for client libraries .
def
object_csek_to_cmek
bucket_name
:,
file_name
:,
encryption_key
:,
kms_key_name
:
# 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 encryption key, which should be the same key originally used to encrypt the object
# encryption_key = "TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g="
# The name of the KMS key to manage this object with
# kms_key_name = "projects/your-project-id/locations/global/keyRings/your-key-ring/cryptoKeys/your-key"
require
"google/cloud/storage"
storage
=
Google
::
Cloud
::
Storage
.
new
bucket
=
storage
.
bucket
bucket_name
,
skip_lookup
:
true
file
=
bucket
.
file
file_name
,
encryption_key
:
encryption_key
file
.
rotate
encryption_key
:
encryption_key
,
new_kms_key
:
kms_key_name
puts
"File
#{
file_name
}
in bucket
#{
bucket_name
}
is now managed by the KMS key
#{
kms_key_name
}
instead of a "
\
"customer-supplied encryption key"
end
What's next
To search and filter code samples for other Google Cloud products, see the Google Cloud sample browser .