如何在 Java 中使用 AWS KMS CMK 和数据密钥实施数据加密和解密?

How do I implement Data Encryption and Decryption using AWS KMS CMK and Data Keys in Java?

我对 AWS 云环境比较陌生,所以我的知识总体上有限。如果这些是简单直接的问题并且询问样本,我预先表示歉意。

我也在 SO 上四处寻找以获取更多信息,但找不到太多。也许我正在寻找错误的东西。任何帮助将不胜感激。

我正在尝试使用 AWS KMS 来加密我的应用程序中的一个数据元素。看完文档后,我的理解如下:

  1. 我的 AWS 账户中需要有一个 CMK。我已经在我的账户中创建了一个 AWS 管理的 CMK。
  2. 记下我从控制台为我的 CMK 获取的 CMK 的密钥 ID 或别名。
  3. 通过传递 KeyID 或别名和 KeySpec 创建一个 GenerateDataKeyRequest 对象。
  4. 使用 awskmsClient.generateDataKey() 方法并传递上述 GenerateDataKeyRequest 对象生成数据密钥。
  5. 以上步骤将给我 GenerateDataKeyResult 对象,该对象将具有数据键的 "plaintext" 和 "ciphertextblob" 值。

我有如下代码:

AWSKMS awsKmsClient = AWSKMSClientBuilder.standard().build();
GenerateDataKeyRequest keyRequest = new GenerateDataKeyRequest()
        .withKeyId("alias/MyKeyAlias")
        .withKeySpec("AES_256");
GenerateDataKeyResult dataKeyResponse = awsKmsClient .generateDataKey(keyRequest );

System.out.println("Plaintext Data Key: " + dataKeyResponse.getPlaintext());
System.out.println("Ciphertext Data Key: " + dataKeyResponse.getCiphertextBlob());

文档说使用 "plaintext" 数据密钥加密我的数据并删除 "plaintext" 数据密钥。

我的第一个问题是:如何使用 "plaintext" 数据密钥加密我的数据?

我无法在文档中找到有关如何执行此操作的位置。或者使用哪个API。 AWSKMSClient class 中有一个“encrypt”方法,但它只能与 CMK 的 KeyID 一起使用,而不能与数据密钥一起使用.还是我理解错了?

然后文档还说要存储 加密数据和“ciphertextblob”数据钥匙。 这在 AWS KMS 术语中称为 Envelope Encryption。我无法弄清楚我该怎么做。在这方面的任何帮助将不胜感激。

根据文档,我们需要按照以下步骤解密:

  1. 使用存储的"ciphertextblob"数据键获取"plaintext"数据键。

  2. 使用上面的"plaintext"数据密钥解密数据

我也有几个问题,如下:

  1. 在数据库中存储加密数据和“ciphertextblob”数据密钥的最佳方式是什么?

  2. 如何从存储的 "ciphertextblob" 数据密钥中获取“纯文本”数据密钥?

  3. 最后,如何使用在上述步骤中获得的 "plaintext" 数据密钥解密我的数据?

如能提供上述问题的示例代码,将不胜感激。或者请为我指明正确的方向以实现上述目标。

谢谢。

您可以使用 Java 加密扩展 (JCE) 来加密或解密数据。我不确定存储数据 ciphertextblob 数据密钥和加密数据的最佳方式是什么,但我相信这应该取决于您的应用程序和要求。要从密文blob中获取明文数据密钥,需要调用KMS DecryptAPI,即使用CMK解密密文数据密钥,得到明文数据密钥。

你应该使用AWS Encryption SDK而且你不必担心这些问题:)

可以找到示例代码 here

My first question is: How do I encrypt my data using the "plaintext" data key?

您可以使用默认的加密功能,我看到您正在使用 Java,您可以看看 my encryption blog

Then the documentation also says to store the encrypted data and "ciphertextblob" data key. This is called Envelope Encryption in AWS KMS terms. I am not able to figure out how do I do it. Any help in this regard will be highly appreciated.

您存储密文(加密数据)和从 generateDataKey 操作返回的 "ciphertextblob" 数据密钥。如何存储数据取决于您(本地磁盘、S3、DB、其他服务..)。

"ciphertextblob" 数据密钥稍后将用于从 kms 请求普通加密密钥,以便您可以解密数据

As per documentation, we need to take the below steps to decrypt:
Use the stored "ciphertextblob" data key to get the "plaintext" data key.
Use the above "plaintext" data key to decrypt the data.

确实,解密操作 returns 来自 "ciphertextblob" 的纯数据加密密钥,因此您可以解密您的数据(同样 - 数据 encryption/decryption 完全取决于您,但强烈建议您使用一些安全标准,例如 AES)

What is the best way to store the encrypted data and "ciphertextblob" data key in a database?

请注意加密数据是二进制的,因此您通常可以看到它们是经过编码的(例如 base64),所以恕我直言,最好的方法是将它们存储为文本 (varchar)。

How do I get the "plaintext" data key from the the stored "ciphertextblob" data key?

调用 decrypt() 操作 - 它 returns 来自 "ciphertextblob"

的纯数据加密密钥

And finally, how do I decrypt my data using the "plaintext" data key I get in the step above?

再次使用默认的加密功能:)