我想知道您是否可以帮我解决以下问题。KMS 和 GCP 中的秘密管理器有什么区别?先感谢您。 https://cloud.google.com/secret-manager/docs/ HB
google-cloud-platform google-cloud-kms google-secret-manager
我的应用程序需要一堆机密才能运行:数据库凭据、API 凭据等。它在 Google App Engine Standard Java 11 中运行。我需要这些机密作为环境变量或作为我应用程序的参数,以便我的框架可以获取它们并相应地建立连接。我的特定框架是 Spring Boot,但我相信 Django、Rails 和许多其他框架使用相同的方法。
这样做的最佳方法是什么?
我对这个问题的答案之一是使用 Google Cloud Key Management,这看起来很有希望,但我不知道如何将这些值转换为 App Engine 中的环境变量。是否可以?我已经阅读 了为服务器到服务器生产应用程序设置身份验证,但我没有看到任何关于如何在 App Engine 中将机密转换为环境变量的指示(我错过了吗?)。
我见过的其他替代方案包括将它们硬编码到app.yaml另一个从未提交并存在于我的机器中的文件中,这意味着我是唯一可以部署的人......我什至无法从另一台机器部署。这对我来说是有问题的。
我见过的另一个潜在解决方案是将问题委托给 Google Cloud Build,以便它从 CKM 获取值/文件并将其推送到 App Engine ( 1 , 2 )。我没有使用 GCB,我怀疑我会,因为它太基础了。
我真的希望 App Engine 有一个像 Heroku 那样的环境变量页面。
google-app-engine google-cloud-platform google-cloud-kms google-secret-manager
我正在尝试使用 google KMS 工具解密令牌。在本地运行它,出于某种原因,加密似乎有效但解密无效。
我正在运行以下代码:
import base64
import googleapiclient.discovery
kms_client = googleapiclient.discovery.build('cloudkms', 'v1')
crypto_keys = kms_client.projects().locations().keyRings().cryptoKeys()
name = "projects/my-project/locations/my-loc/keyRings/my-kr/cryptoKeys/my-key"
request = crypto_keys.decrypt(name=name, body={'ciphertext': base64.b64encode("my text").decode('ascii')})
response = request.execute()
Run Code Online (Sandbox Code Playgroud)
最后一行返回 400 错误:
HttpError: <HttpError 400 when requesting https://cloudkms.g[...]ion:decrypt?alt=json
returned "Decryption failed: verify that 'name' refers to the correct CryptoKey.">
Run Code Online (Sandbox Code Playgroud)
然而,这个名字实际上似乎是正确的。令人惊讶的是,通过替换对decryptby的调用encrypt,我获得了有效的输出。
我是否遗漏了一个明显的错误,还是应该在项目的 github 上打开一个问题?
编辑:我试图解密纯文本,这当然没有多大意义(但错误消息在某种程度上误导了我)。
我正在尝试创建一个 Cloud Build 触发器,其中使用 Cloud KMS 对秘密环境变量进行加密并存储为 Cloud Build 中的替换变量。这样我的云构建 yaml 是相当通用的,并且在我们部署到的所有环境中都是相同的。
这个云构建 yaml 工作正常:
steps:
- name: 'ubuntu'
entrypoint: 'bash'
args: ['-c', 'echo "$$APP_NAME HAS A VALUE $$HELLO_WORLD"']
env:
- 'APP_NAME=${_APP_NAME}'
secretEnv:
- 'HELLO_WORLD'
secrets:
- kmsKeyName: 'projects/my-first-cicd-project/locations/europe-west1/keyRings/keyring-dev/cryptoKeys/key-backend'
secretEnv:
HELLO_WORLD: xxxxxxxxxxx
Run Code Online (Sandbox Code Playgroud)
构建步骤生成此日志行:
My App Name HAS A VALUE Hello there world!
Run Code Online (Sandbox Code Playgroud)
完全符合预期。
现在对于不起作用的事情,或者至少我无法上班。假设我想让密钥环名称动态化。然后我将该 yaml 中的“keyring-dev”替换为${_KMS_KEYRING_NAME}. 这将产生如下错误:
invalid build: failed to check access to "projects/my-first-cicd-project/locations/europe-west1/keyRings/${_KMS_KEYRING_NAME}/cryptoKeys/key-backend"
Run Code Online (Sandbox Code Playgroud)
如果我将 YAML 中的 base64 字符串(以“CiQAH...”开头)更改为诸如 ${_KMS_VAR_HELLO_WORLD} 之类的替换变量,我将收到此错误:
failed unmarshalling build config cloudbuild.yaml: illegal …Run Code Online (Sandbox Code Playgroud) 我正在使用 Google Cloud Functions 构建一个 http 端点。我有一个加密的机密存储为文件,该文件在函数中加载和解密,以防止我的机密存储在代码中。通常我从 Google Cloud Storage 动态加载一些东西,但似乎 KMS 更适合这个目的。
使用 KMS 的代码如下所示:
getCredentials: async function () {
const kms = require('@google-cloud/kms');
const client = new kms.KeyManagementServiceClient();
const fs = require('fs');
let ciphertext = (fs.readFileSync('secret.enc')).toString('base64')
const name = client.cryptoKeyPath(
'[project]',
'global',
'[keyring]',
'[key]'
);
Run Code Online (Sandbox Code Playgroud)
一切都在本地运行良好,但在使用 http 触发器调用时,我似乎无法使该函数正常工作。检查日志我看到了这个:
textPayload: "Error: Permission 'cloudkms.cryptoKeyVersions.useToDecrypt' denied for resource 'projects/[projectname]/locations/global/keyRings/[keyring]/cryptoKeys/[key]'.
at Http2CallStream.call.on (/srv/functions/node_modules/@grpc/grpc-js/build/src/client.js:96:45)
at Http2CallStream.emit (events.js:194:15)
at Http2CallStream.EventEmitter.emit (domain.js:459:23)
at process.nextTick (/srv/functions/node_modules/@grpc/grpc-js/build/src/call-stream.js:71:22)
at process._tickCallback (internal/process/next_tick.js:61:11)"
Run Code Online (Sandbox Code Playgroud)
我已经尝试了各种可用的 IAM 权限(包括所有者),所以似乎我必须有更深层次的误解。
这可能与我无法让 Google Cloud Build …
google-cloud-functions google-cloud-kms google-cloud-iam google-cloud-build
当对称加密与谷歌Cloud的KMS,谷歌云自动选择主键的版本:
每个对称加密密钥都有一个指定的主要版本,用于在那个时间点加密数据。为了使密钥可用于加密数据,它需要有一个已启用的主密钥版本。
当密钥用于加密明文时,其主密钥版本用于加密该数据。关于使用哪个版本加密数据的信息存储在数据的密文中。在任何给定的时间点,只有一个密钥版本可以是主要版本。
该EncryptResponse包括密文,并使用该密钥的版本。
如果在加密的时候没有保存密钥的版本,以后是否可以确定密钥的版本?密钥版本存储在密文中,KMS 服务能够确定要解密的密钥版本,但DecryptResponse仅包含明文,不包含密钥版本。
编辑:我找到了答案。滚动到这个问题的底部。
我在 NodeJS 身份验证服务器上工作,我想使用 google 签名对 JSON Web 令牌 (JWT) 进行签名。
我正在使用 Google Cloud Key Management Service (KMS) 并创建了一个密钥环和一个非对称签名密钥。
这是我获取签名的代码:
signatureObject = await client.asymmetricSign({ name, digest })
signature = signatureObject["0"].signature
Run Code Online (Sandbox Code Playgroud)
我的 Google 签名对象如下所示:
我的问题:如何使用 Google 签名签署 JWT?
或者换句话说,我如何将 Google 签名连接到 JWT 的 (header.payload)?
JWT 应该如下所示:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ. (GoogleSignature)
Run Code Online (Sandbox Code Playgroud)
我正在使用的代码:
签名:
async function sign(message, name) {
hashedMessage = crypto.createHash('sha256').update(message).digest('base64');
digest = { 'sha256': hashedMessage }
signatureObject = await client.asymmetricSign({ name, digest }).catch((err) => console.log(err))
signature = signatureObject["0"].signature
signJWT(signature)
}
Run Code Online (Sandbox Code Playgroud)
创建 JWT: …
我有一些代码可以从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
}
Run Code Online (Sandbox Code Playgroud)
棘手的部分是,我正在使用Google KMS来管理用于加密文件的密钥(Google的“客户管理的加密密钥”方案)。我的理解是这种加密发生在Google的一端。
我发现使用Go CDK的唯一解决方案是使用Google KMS加密文件,然后上传加密的Blob。没有办法像以前使用Go CDK一样指定加密密钥吗?
谢谢
出于某种原因,我似乎无法更新该us-central1地区的密钥。我的 IAM 具有更新和列表角色,我使用以下代码:
import google.cloud.kms as kms
self.client = kms.KeyManagementServiceClient()
name = 'client-1'
key_path = self.client.crypto_key_path(config.PROJECT, config.KMS_LOCATION, config.KMS_RING, name)
update_mask = {'paths': ['rotation_period', 'next_rotation_time']}
self.client.update_crypto_key({
'name': key_path,
'rotation_period': {'seconds': 0},
'next_rotation_time': {'seconds': 0}
}, update_mask)
Run Code Online (Sandbox Code Playgroud)
它给了我以下错误:
google.api_core.exceptions.NotFound: 404 该请求涉及位置“us-central1”,但被发送到位置“global”。Cloud KMS 在“us-central1”中不可用,或者请求被错误路由。
奇怪的是,列表和获取工作正常。我也看到了一个解决方案,他们改变了客户端的传输参数,但我似乎找不到正确的地址。
提前致谢 !
我一直在尝试找到一种在 GCP 中存储机密的方法。我探索过 Google Cloud KMS。它似乎仅用于创建加密密钥,可用于加密 GCP 存储元素。或者,也许我错过了什么。我也看到了,有一种方法可以集成HashicorpVault。但是,我一直在 GCP 本身中寻找解决方案,例如 Azure Vault。我的最终目标是将秘密存储在某处并在云函数中使用它。
任何帮助,将不胜感激。谢谢!
google-cloud-platform azure-keyvault hashicorp-vault google-cloud-kms google-secret-manager