Google Cloud KMS 解密问题

Google Cloud KMS issue with decrypt

我是 Cloud KMS 的新手,我开始完全按照所写的内容进行操作 here

我通过 运行 这个命令

加密了以 UTF-8 格式保存的数据文件
gcloud kms encrypt --location global --keyring ring --key key --plaintext-file /path_to_file --ciphertext-file /path_to_enc --project myProject 

然后我的加密数据以这种格式出现在我新创建的加密文件中

$�]ˋLݿ���yHI�lS�`&�Nt�b{%�U��   �&�A���XaL��d

这是我读取加密文件数据的方式:

 static Properties properties = new Properties();

static {

    try {

        InputStream in = new Credentials().getClass().getResourceAsStream("path_to_enc_file");
        byte[] encryptedData = IOUtils.toByteArray(in);

        byte[] decryptedBytes = decrypt(EnvironmentVariable.getProjectId(), "global", "ring", "key", encryptedData);
        ByteArrayInputStream bis = new ByteArrayInputStream(decryptedBytes);

        properties.load(bis);           
        in.close();
        bis.close();
    } catch (IOException e1) {
        e1.printStackTrace();
    }
}

现在每当我尝试用这个函数解密它时:

public static byte[] decrypt(
    String projectId, String locationId, String keyRingId, String cryptoKeyId, byte[] ciphertext)
    throws IOException {

  // Create the KeyManagementServiceClient using try-with-resources to manage client cleanup.
  try (KeyManagementServiceClient client = KeyManagementServiceClient.create()) {

    // The resource name of the cryptoKey
    String resourceName = CryptoKeyName.format(projectId, locationId, keyRingId, cryptoKeyId);

    // Decrypt the ciphertext with Cloud KMS.
    DecryptResponse response = client.decrypt(resourceName, ByteString.copyFrom(ciphertext));

    // Extract the plaintext from the response.
    return response.getPlaintext().toByteArray();
  }
}

它抛出这个

{
  "code" : 400,
  "errors" : [ {
    "domain" : "global",
    "message" : "Decryption failed: the ciphertext is invalid.",
    "reason" : "badRequest"
  } ],
  "message" : "Decryption failed: the ciphertext is invalid.",
  "status" : "INVALID_ARGUMENT"
}

密钥类型为:Symmetric encrypt/decrypt 默认算法:Google symmetric key

戒指位置:global

你能帮我看看 google 文档中缺少什么吗?

更新:正如 bdhess 在评论中所说,这可能是由于 Maven "helpful" 并且在构建过程中损坏了数据。请参阅 Maven docs 了解如何避免这种情况。

下面的解决方案也有效,但不太直接。


我和 Tamer 聊了一会儿,找到了解决方法:

  • 在将 gcloud 的输出包含在 src/main/resources.
  • 的文件中之前,先用 base64 对输出进行编码
  • java.util.Base64读取文件后解码。
  • 将解码后的字节传递给 KMS API。

出于某种原因,在使用 gcloud 创建文件和使用 getResourceAsStream() 读取字节之间的字节被损坏。从上面的代码中我看不出损坏会发生在哪里,而且似乎应该完全支持读取二进制资源。但是在 Tamer 的案例中有些地方出了问题。

我会在本周的某个时候尝试重现它。

我做了这些修改,然后在@hjfreyer

的大力帮助下它就像一个魅力

1- 加密纯文本秘密我这样做了

  • 运行 这个命令 -->

    gcloud kms encrypt --location global --plaintext-file PATH_TO_SECRET_FILE --ciphertext-file PATH_TO_TMP_FILE --project myProject --key key --keyring ring

  • 对结果进行 base64 编码 -->

    base64 PATH_TO_TMP_FILE > PATH_TO_FINAL_ENC_FILE

  • 从 FINAL_ENC_FILE 文件中删除新行

2- 要先解密数据,我需要对其进行 base64 解码,然后将其传递给解密 KMS 函数

InputStream in = new Credentials().getClass().getResourceAsStream("PATH_TO_FINAL_ENC_FILE");
            byte[] encryptedData = IOUtils.toByteArray(in);


            byte[] decryptedBytes = decrypt(EnvironmentVariable.getProjectId(), "global", "ring", "key", Base64.getDecoder().decode(encryptedData));

将秘密从文件解密为明文文件:

cat secret.enc | gcloud kms decrypt \
  --location=global \
  --keyring=keyring \
  --key=key \
  --ciphertext-file=- \
  --plaintext-file=decrypted_secret.txt