如何从 Google 云存储中解密文件?

How to decrypt file from Google Cloud Storage?

我有一个加密文件存储在 Google Cloud Storage 存储桶中,该存储桶是使用以下命令行生成的:

gcloud kms encrypt --location=global --keyring=my-keyring --key=-my-key --plaintext-file=my-file --ciphertext-file=my-file.enc

我现在正尝试使用以下代码在云 运行 服务中解密此类文件:

const kms = require('@google-cloud/kms');
const client = new kms.KeyManagementServiceClient();
const file = storage.bucket("my-bucket").file('my-file.enc');
const name = client.cryptoKeyPath( 'projectId', 'global', 'my-keyring', 'my-key' );
let encrypted = (await file.download())[0];
const [result] = await client.decrypt({name, encrypted });

我收到以下错误:

Error: Decryption failed: verify that 'name' refers to the correct CryptoKey.

根据 ,这是误导性的,应被视为未正确破译。我无法摆脱我在某处缺少 base64 encode/decode 的感觉,但我似乎找不到解决方案。

如果我 运行 从命令行解密它就可以正常工作。

非常感谢任何帮助。

谢谢。

编辑: 多亏了这个很棒的社区,问题才得以解决。以下是完成这项工作的步骤,以防其他人遇到同样的问题:

使用以下命令行加密文件并通过网络上传UI。

gcloud kms encrypt --location=global --keyring=my-keyring --key=-my-key --plaintext-file=my-file --ciphertext-file=my-file.enc

使用以下代码解密:

const kms = require('@google-cloud/kms');
const client = new kms.KeyManagementServiceClient();
const file = storage.bucket("my-bucket").file('my-file.enc');
const name = client.cryptoKeyPath( 'projectId', 'global', 'my-keyring', 'my-key' );
let encrypted = (await file.download())[0];
const ciphertext = encrypted .toString('base64');
const [result] = await client.decrypt({name, ciphertext});
console.log(Buffer.from(result.plaintext, 'base64').toString('utf8'))

我在这里发现了一些东西:

  1. 假设您的命令是正确的,my-file-enc 应该是 my-file.enc 而不是(点与破折号)

  2. 验证 projectId 是否设置正确。如果您从环境变量 console.log 填充它,并确保它与您在其中创建 KMS 密钥的项目相匹配。 gcloud 默认为一个项目(你可以通过 运行 gcloud config list 并检查 core/project 属性来找出哪个项目)。如果您在项目 foo 中创建了密钥,但您的 Cloud 运行 服务正在项目 bar 中查找,它将失败。

  3. 使用--ciphertext-file写入文件时,数据不是base64编码。但是,您正在 创建一个二进制文件。您如何将该二进制字符串上传到 Cloud Storage?最可能的罪魁祸首似乎是编码问题(ASCII vs UTF),它可能导致解密失败。确保您以二进制形式写入和读取文件。

  4. 查看Cloud KMS Nodejs文档,指定密文应该是"exactly as returned from the encrypt call"。文档说 KMS 响应是 base64 encoded string,因此您可以尝试在 Cloud 运行 服务 中对数据进行 base64 编码,然后再 将其发送到 Cloud KMS 进行解密:

    let encrypted = (await file.download())[0];
    let encryptedEncoded = encrypted.toString('base64');
    const [result] = await client.decrypt({name, encrypted});
    
  5. 你可能想看看Berglas, which automates this process. There are really good examples for Cloud Run with node

  6. 更多模式,查看Secrets in Serverless