1

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

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

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

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 编码/解码的感觉,但我似乎没有找到解决方案。

如果我从命令行运行解密它就可以了。

非常感谢任何帮助。

谢谢。

编辑:感谢这个很棒的社区,问题解决了。以下是完成这项工作的步骤,以防其他人面临同样的问题:

使用以下命令行加密文件并通过 Web 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'))
4

1 回答 1

1

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

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

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

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

  4. 查看 Cloud KMS Nodejs 文档,它指定密文应该“与加密调用返回的完全相同”。文档说 KMS 响应是base64 编码字符串,因此您可以尝试在 Cloud Run 服务中对数据进行 base64 编码,然后再将其发送到 Cloud KMS 进行解密:

    let encrypted = (await file.download())[0];
    let encryptedEncoded = encrypted.toString('base64');
    const [result] = await client.decrypt({name, encrypted});
    
  5. 您可能想看看Berglas,它可以自动执行此过程。Cloud Run with node有很多很好的例子。

  6. 有关更多模式,请查看无服务器中的秘密

于 2019-07-29T12:39:33.547 回答