繁体   English   中英

如何使用带有Java或AWSKmsClient的AWS Encryption SDK解密AWS KMS密码

[英]How to decrypt AWS KMS cipher with AWS Encryption SDK with Java or AWSKmsClient

我想使用带有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对其进行解密。

根据此链接 ,AWS Encryption SDK和AWS KMS之间似乎有些区别:

适用于Java的AWS Encryption SDK并不意味着与aws kms命令行工具兼容。 简而言之,AWS Encryption SDK利用KMS提供了比单独的KMS更通用的加密功能。

我也无法通过AWSKmsClient做到这一点,我缺少什么吗? 有没有更好的方法来实现这一目标?

这里的困惑归结为直接通过AWS开发工具包使用AWS KMS和使用AWS Encryption SDK之间的区别。

AWS Encryption SDK使用KMS(或其他密钥提供者)作为信封加密格式的一部分[1]。 因此,您引用的代码段是正确的:AWS Encryption SDK的输出无法直接由KMS解密,反之亦然。

但是,所有AWS加密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解码。 您必须提供原始字节。 因此,如果您在解密请求中将base64编码的字符串提供给AWSKmsClient ,则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

“ AWS Encryption SDK的所有特定于语言的实现,包括AWS Encryption CLI,都是可以互操作的。” 引自aws docs 因此问题正文中缺少的链接必须包含虚假信息。

文档中有基本的例子。 用您的密钥ID初始化KmsMasterKeyProvider应该可以为您完成。

为什么不将加密部分包装在使用AWS Encryption SDK的Java程序中,这样您就不必担心“互操作性”了?

我已经设法使用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
  }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM