“'密文'(TYPE_BYTES)处的无效值”

The*_*mer 3 javascript encryption node.js google-cloud-platform google-cloud-kms

情况:

我正在尝试从我的谷歌云存储桶下载和解密一些数据。

对于加密和解密,我使用:

https://cloud.google.com/kms/docs/quickstart#decrypt_data

遗憾的是,我收到一个错误:“‘密文’(TYPE_BYTES)处的值无效”。

我知道密文是正确的,我相信这可能是 Google KMS API 预期的数据类型的问题,即:检索加密数据时,我的代码在将 POST 请求发送到 Google KMS API 之前以某种方式更改了它的类型.

我做错了什么,我该如何解决?


代码:

gcs.bucket(bucketName)
.file('mysecret.txt.encrypted.txt')
.download({ destination: 'mysecret.txt.encrypted.txt' })
.then(() => {
    fs.readFile('mysecret.txt.encrypted.txt', (err, data) => {
        if (err) throw err;
        console.log("DATA: "+data);
        var formData = {
           ciphertext: data, 
        };
        request.post({
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ...'
            },
            url: 'https://cloudkms.googleapis.com/v1/projects/kms-raimarketplace/locations/global/keyRings/.../cryptoKeys/...:decrypt',
            form: formData
        },
        function (err, httpResponse, body) {
            if (err) {
                console.log("ERROR: "+err);
            }
            else {
                console.log("BODY: "+body);
            }
            console.log(err, body);
        });
    });
}).catch(e => {
    console.error('getEnv.js: There was an error: ${JSON.stringify(e, undefined, 2)}');
});
Run Code Online (Sandbox Code Playgroud)

输出:

BODY: {
  "error": {
    "code": 400,
    "message": "Invalid value at 'ciphertext' (TYPE_BYTES), ",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.BadRequest",
        "fieldViolations": [
          {
            "field": "ciphertext",
            "description": "Invalid value at 'ciphertext' (TYPE_BYTES), "
          }
        ]
      }
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

Tim*_*rks 5

我认为您可能没有传递 base64 编码的密文;这是此类解码失败时返回的错误(尽管此消息也可能出现在其他情况下)。

我创建了一个世界通用的密钥,任何人都可以用它来解密,你应该可以用它来测试。

这是我用来创建密文的代码。(您将无法运行此代码,因为我尚未打开密钥的加密权限。此代码直接来自Cloud KMS 快速入门,其中插入了我的密钥并内嵌了 base64 编码)

curl -s -X POST "https://cloudkms.googleapis.com/v1/projects/cloud-kms-demonstration/locations/global/keyRings/insecure-example-key-ring/cryptoKeys/insecure-example-key:encrypt" \
-d "{\"plaintext\":\"$(echo hello world | base64)\"}" \
  -H "Authorization:Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type:application/json"
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我得到以下输出(我在以我的 gmail 帐户登录的 GCP Cloud Shell 中运行它,我已授予密钥加密权限):

{
  "name": "projects/cloud-kms-demonstration/locations/global/keyRings/insecure-example-key-ring/cryptoKeys/insecure-example-key/cryptoKeyVersions/1",
  "ciphertext": "CiQAOay+bYR0HXjYHihHZmjPnu0ZEdOm4/HW4S6ZBifwWfFnL1QSNQBA6mRpHiq1MPQ7MerLyJ+gFJdeQooBFU0K0YmGlxRy5Ke/2eV16yR0viHPII6flFpzxnmD"
}
Run Code Online (Sandbox Code Playgroud)

然后我运行了以下命令;您会看到我从加密操作的输出中复制并粘贴了密文。任何经过身份验证的人都可以运行此命令来使用我的密钥解密密文,所以现在可以随意运行它:

curl -s -X POST "https://cloudkms.googleapis.com/v1/projects/cloud-kms-demonstration/locations/global/keyRings/insecure-example-key-ring/cryptoKeys/insecure-example-key:decrypt" \
  -d "{\"ciphertext\":\"CiQAOay+bYR0HXjYHihHZmjPnu0ZEdOm4/HW4S6ZBifwWfFnL1QSNQBA6mRpHiq1MPQ7MerLyJ+gFJdeQooBFU0K0YmGlxRy5Ke/2eV16yR0viHPII6flFpzxnmD\"}" \
  -H "Authorization:Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type:application/json"
Run Code Online (Sandbox Code Playgroud)

我得到了结果:

{
  "plaintext": "aGVsbG8gd29ybGQK"
}
Run Code Online (Sandbox Code Playgroud)

这是我的明文的 base64 编码:

$ echo "aGVsbG8gd29ybGQK" | base64 -d
hello world
Run Code Online (Sandbox Code Playgroud)

如果我使用的是库,它可能会将 base64 编码作为传输要求的一部分进行处理。所以希望你可以使用这个已知好的密文和一个可以解密的密钥来调试你自己的代码。祝你好运!

注意:正如名称所示,不要使用我为任何安全提供的密钥(这就是我没有打开密钥加密权限的原因)。