【问题标题】:How to store my key for encryption on aws?如何在aws上存储我的加密密钥?
【发布时间】:2020-10-29 20:12:54
【问题描述】:

我正在开发运行在 ec2 服务上的 rest api 系统。

我的要求是

  1. 使用 AES256 对纯文本进行加密/解密
  2. 使用 pbkdf2 生成密钥
  3. 将密钥存储在 aws 云系统上
  4. Java

我尝试使用 KMS 和 Crypto sdk,但它不起作用。 (ex) 当我用相同的明文调用方法时,每次加密值的结果都会改变。

你有什么想法吗?

public String encrypt(String text) {
    String plaintext = text;
    try {
        ByteBuffer byteBuffer = getByteBuffer(plaintext);
        EncryptRequest encryptRequest = new EncryptRequest().withKeyId(key_arn).withPlaintext(byteBuffer);
        EncryptResult encryptResult = client.encrypt(encryptRequest);
        String ciphertext = getString(java.util.Base64.getEncoder().encode(encryptResult.getCiphertextBlob()));
        plaintext = ciphertext;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return plaintext;
}

public String decrypt(String text) {
    String bb = null;
    try {
         byte[] ciphertextBytes = text.getBytes();

        DecryptRequest request = new DecryptRequest();
        request.setCiphertextBlob(ByteBuffer.wrap(ciphertextBytes));

        DecryptResult result = client.decrypt(request);

        // Convert to byte array
        byte[] plaintext = new byte[result.getPlaintext().remaining()];
        ByteBuffer a = result.getPlaintext().get(plaintext);
        bb = getString(a);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return bb;
}

【问题讨论】:

  • "但它不起作用" - 您能否提供一个示例,说明如何使用 KMS 以使其不起作用?
  • @Marcin 我的代码

标签: amazon-web-services encryption cryptography


【解决方案1】:

这是一个很难简洁回答的问题,因为有很多细节和背景知识涉及加密和正确使用 AWS 加密功能。

首先针对您的具体问题 - 来自同一明文的不同值是可以的,并且是预期的。 Encrypt 为相同的纯文本返回不同的值,因为它将附加数据附加到纯文本,例如 Initialization Vector (IV)。这是一种在纯文本中精确包含非确定性数据的方法,以便您在使用相同密钥时不会从相同的纯文本中得到完全相同的密文。

但更重要的是,请注意 EncryptDecrypt 不是通用工具 - 它们旨在处理小型有效负载 (Data Keys。因此,您从这里去哪里将取决于您要加密的数据类型。如果只需要解密密码这样的小值,可以继续Encrypt/Decrypt,不用担心两个Encrypt操作会产生不同的密文。如果您需要加密文件或其他任意数据块,请继续阅读。

AWS 提倡Envelope Encryption 的概念,即用于实际加密/解密的密钥与其保护的数据一起存储,并且本身通过单独的主密钥进行加密/解密。在 AWS 案例中,它是 Customer Master Key (CMK),它永远不会离开 KMS。

因此,您可以使用 Encrypt 加密您生成的加密密钥,或者您可以使用 AWS 方法 GenerateDataKey 来 1) 创建密钥并 2) 为您加密。这将返回密钥的明文(base64)和密文版本。使用内存中的明文,将密文存储到磁盘。

更典型的工作流程是这样的:

  • 调用GenerateDataKey - 您需要指定KeyIdKeySpecAES_128AES_256)。还有一些选项可以生成非对称密钥。
  • 结果包括生成密钥的纯文本和加密版本。存储加密版本。
  • 稍后,当您需要使用密钥时,请致电Decrypt
  • 使用来自 Decrypt 方法的明文作为本地加密代码中的密钥。

AWS 实际上提供了一个单独的库来为您完成所有这些工作 - AWS 加密 SDK,支持包括 Java 在内的多种语言。我没有广泛使用它,但它提供了通过最佳实践(哪些算法、主密钥与数据密钥等)进行信封加密的框架。看看(下面的链接)。

希望这会有所帮助;加密很难做到正确。

更多信息:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    相关资源
    最近更新 更多