使用 KMS 时尝试将某些代码转换为 Go CDK
Posted
技术标签:
【中文标题】使用 KMS 时尝试将某些代码转换为 Go CDK【英文标题】:Attempting to convert some code to Go CDK when using KMS 【发布时间】:2019-08-13 23:41:26 【问题描述】:我有一些代码可以从 Google Cloud Storage 上传和下载文件。下面是一个缩略的例子:
import (
"context"
"io"
"cloud.google.com/go/storage"
)
func upload(bucket, keyName, path string, reader io.Reader) error
ctx := context.Background()
client, err := storage.NewClient(ctx)
if err != nil
return err
defer client.Close()
obj := client.Bucket(bucket).Object(path)
writer := obj.NewWriter(ctx)
defer writer.Close()
writer.KMSKeyName = keyName
if _, err = io.Copy(writer, reader); err != nil
return err
if err = writer.Close(); err != nil
return err
return nil
棘手的部分是我使用 Google KMS 来管理用于加密文件的密钥(Google 所谓的“客户管理的加密密钥”方案)。我的理解是这种加密发生在 Google 端。
我发现使用 Go CDK 的唯一解决方案是使用 Google KMS 加密文件,然后上传加密的 blob。有没有办法像我以前用 Go CDK 一样指定加密密钥?
谢谢
【问题讨论】:
【参考方案1】:如果您需要在 Go CDK 中使用特定于提供程序的设置,您可以使用各种 As
functions 来获取底层提供程序 API 的句柄。在这种情况下,您可能希望使用blob.WriterOptions.BeforeWrite
选项。这样做的好处是,如果您决定稍后切换存储桶提供程序(例如,用于单元测试),BeforeWrite
将不起作用。
import (
"context"
"io"
"cloud.google.com/go/storage"
"gocloud.dev/blob"
_ "gocloud.dev/blob/gcsblob" // link in "gs://" URLs
)
func upload(ctx context.Context, bucket, keyName, path string, reader io.Reader) error
bucket, err := blob.OpenBucket(ctx, "gs://" + bucket)
if err != nil
return err
defer bucket.Close()
writeCtx, cancelWrite := context.WithCancel(ctx)
defer cancelWrite()
writer, err := bucket.NewWriter(writeCtx, path, &blob.WriterOptions
// Use BeforeWrite to set provider-specific properties.
BeforeWrite: func(asFunc func(interface) bool) error
var gcsWriter *storage.Writer
// asFunc returns true if the writer can be converted to the type
// pointed to.
if asFunc(&gcsWriter)
gcsWriter.KMSKeyName = keyName
return nil
,
)
if err != nil
return err
if _, err := io.Copy(writer, reader); err != nil
cancelWrite() // Abort the write to the bucket.
writer.Close()
return err
if err := writer.Close(); err != nil
return err
return nil
(虽然与您的问题没有直接关系,但我在代码中添加了中止写入错误,以避免将部分对象上传到您的存储提供程序。我们正在添加将演示如何使用 Go CDK API 执行常见任务的文档将来,请参阅#1576。)
【讨论】:
【参考方案2】:您发布的代码是正确的。具体来说,此行指示 API 使用提供的 Cloud KMS 密钥加密数据:
writer.KMSKeyName = keyName
可能会遇到的一些事情:
确保您的 Cloud KMS 密钥和 Cloud Storage 存储分区位于同一区域。例如,如果您的存储桶位于“美国”,则您的 KMS 密钥也必须位于“美国”。
确保您已授予您的 Cloud Storage 服务帐号访问权限以使用 KMS 密钥。您可以find the email of your Cloud Storage service account,然后授予它使用您的 KMS 密钥的权限:
$ gcloud kms keys add-iam-policy-binding my-key \
--project my-project \
--keyring my-keyring \
--location us \
--member serviceAccount:service-1234567890@gs-project-accounts.iam.gserviceaccount.com \
--role roles/cloudkms.cryptoKeyEncrypterDecrypter
确保您正在捕获从上游 upload
返回的错误。所有这些故障模式都会导致错误,所以我想知道它是否在某个地方丢失了。
证明它有效:
// Completely unmodified version of your `upload` function
func main()
bucket := "<hidden>"
kmsKey := "projects/<hidden>/locations/us/keyRings/kr/cryptoKeys/k"
if err := upload(bucket, kmsKey, "foo", strings.NewReader("hello world")); err != nil
log.Fatal(err)
执行时,这会在 CMEK 支持的 GCS 中正确创建一个对象。
【讨论】:
以上是关于使用 KMS 时尝试将某些代码转换为 Go CDK的主要内容,如果未能解决你的问题,请参考以下文章
将安全字符串参数插入 ssm 参数存储的 CDK 和自动化?
将 Bref Lambda 自定义运行时与 AWS CDK 一起使用时出现错误 libncurses.so.6
使用 KMS 托管 CMK 时复制到 redshift 失败并出现错误
将 AWS KMS ECDSA_SHA_256 签名从 DER 编码的 ANS.1 格式转换为 JWT base64url 编码的 R || NodeJS/Javascript 中的 S 格式