我想使用带有Java的AWSKmsClient或AWS Encryption SDK来解密我使用AWS CLI
加密的消息
我使用以下方法创建了加密的消息:
aws kms encrypt --key-id 123421-4032-412c-4321-eds42d1a1b432 --plaintext MyText --output text --query CiphertextBlob
它为我生成了以下内容:
ADCCAHhJotXoy8910T/Pd8PXVaF/Xkg+9NrF9QTy/XlW7rTtUAH6zACj9MbEY1cS7526GfscAAAAZjBkBgkqhkiG9w0BBwagVzBVAgEAMFAGCSqGSIb3DQEHATAeBglghkgBZDEEAS4wEQQMGmYHb67SV66h/eE0AgEQgCONMNda4kVsSi9sPAXXts2F0N/mwjSlIB2ngJcAyxymnltrHQ==
我想将此代码传递给我的scala-spark代码,并使用AWSKmsClient或使用Java的AWS Encryption SDK对其进行解密。
基于this link,AWS Encryption SDK和AWS KMS之间似乎有些区别:
适用于Java的AWS Encryption SDK并不意味着与 aws kms命令行工具。简而言之,AWS Encryption SDK利用 KMS提供比单独的KMS更通用的加密功能
我也无法使用AWSKmsClient做到这一点,我缺少什么吗?有没有更好的方法来实现这一目标?
答案 0 :(得分:1)
这里的困惑归结为直接通过AWS开发工具包使用AWS KMS和使用AWS Encryption SDK之间的区别。
AWS Encryption SDK使用KMS(或其他密钥提供者)作为信封加密格式的一部分[1]。因此,您引用的代码片段是正确的:AWS Encryption SDK的输出无法直接由KMS解密,反之亦然。
但是,所有AWS Encryption SDK实现 彼此兼容 。
如果要通过CLI加密某些内容,然后可以传递给Java / JVM代码进行解密,那么使用AWS Encryption SDK CLI和适用于Java的AWS Encryption SDK绝对可以实现。
来源:我编写了适用于Python [2]和CLI [3]的AWS Encryption SDK,并就适用于C [4]的AWS Encryption SDK以及我们的文档[5]提出了建议。
关于为什么您不能使用AWSKmsClient
来解密使用AWS CLI直接调用KMS所收到的值的原因,根据收到的错误有很多可能性。
一种可能性是您可能没有对CMK的Decrypt
权限。这应该导致了KMS的权限错误。
另一种可能性是您提供了无效的密文。 AWS CLI自动返回它从KMS接收的CiphertextBlob
二进制数据的base64编码,然后再将其返回,因为大多数Shell不能很好地处理二进制数据。但是,AWSKmsClient
在将任何内容发送到KMS之前不会自动对其进行base64解码。您必须提供原始字节。因此,如果您在解密请求中向AWSKmsClient
提供base64编码的字符串,则KMS将抛出错误,指出您提供了无效的密文。
[1] https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/message-format.html
[2] https://aws-encryption-sdk-python.readthedocs.io/en/latest/
[3] https://aws-encryption-sdk-cli.readthedocs.io/en/latest/
[4] https://github.com/awslabs/aws-encryption-sdk-c
[5] https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/introduction.html
答案 1 :(得分:0)
“ AWS Encryption SDK的所有特定于语言的实现,包括AWS Encryption CLI,都是可以互操作的。”引自aws docs。因此问题正文中缺少的链接必须包含虚假信息。
documentation中有一些基本示例。使用您的密钥ID初始化KmsMasterKeyProvider应该可以为您完成。
为什么不将加密部分包装在使用AWS Encryption SDK的Java程序中,这样就不必担心“互操作性”了?
答案 2 :(得分:0)
我设法使用了AWSKMSClient
import java.nio.charset.StandardCharsets
import com.amazonaws.services.kms.{AWSKMS, AWSKMSClientBuilder}
import com.amazonaws.services.kms.model.DecryptRequest
import java.nio.ByteBuffer
import com.google.common.io.BaseEncoding
object KMSUtils {
val keyId = "arn:aws:kms:us-east-1:{Account ID}:key/{KEY ID}"
def decrypt(base64EncodedValue: String): String = {
val kmsClient: AWSKMS = AWSKMSClientBuilder.standard.build
val textDecoded: ByteBuffer = ByteBuffer.wrap(BaseEncoding.base64().decode(base64EncodedValue))
val req : DecryptRequest = new DecryptRequest().withCiphertextBlob(textDecoded)
val plainText : ByteBuffer = kmsClient.decrypt(req).getPlaintext
val printable = StandardCharsets.UTF_8.decode(plainText).toString
return printable
}
}