AES-256加密:从我的固定字符串生成256位(32字节)密钥

时间:2014-07-23 13:19:32

标签: java encryption cryptography aes

我想使用AES256加密text,我想使用我的电子邮件test@gmail.com作为key来加密它。

这就是我的尝试:

String key = "test@gmail.com";
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

byte iv[] = SOME_RANDOM_32_BYTES;
IvParameterSpec ivSpec = new IvParameterSpec(iv);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

byte[] encryptedResult = cipher.doFinal(text.getBytes("UTF-8"));

当我运行上面的代码时,我得到 InvalidKeyException

java.security.InvalidKeyException: Key length not 128/192/256 bits.

我在网上查了一下,原因是我的关键不是128/192/256位。我的问题是,如何从我的电子邮件字符串test@gmail.com生成256位(32字节)密钥?

3 个答案:

答案 0 :(得分:1)

您可以使用SHA256将密钥字符串(test@gmail.com)哈希到256位值。

MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(yourEmail.getBytes());
byte[] encryptionKey = md.digest();

答案 1 :(得分:0)

这可能有多种原因。其中一个在下面。 通常,当您的JRE中没有更新策略时会出现此错误。 默认情况下,Java为AES提供128,对于256,我们必须提供Java提供的新策略。

答案 2 :(得分:0)

你不应该自己烘烤加密!(除非你对此事非常了解,否则就是这样。)

您应该使用现有(和审核)加密库。

另外,你不应该使用可猜测的字符串,例如你的电子邮件地址作为密码。请查看有关如何选择一个好密码的建议。

现在我已经说过了,这里有更多细节。

实施基于密码的加密的正确方法是使用KDF(Key Derivation Function)从密码生成加密密钥。以下是一些可用于此任务的KDF:Argon2ScryptBcryptPBKDF2

密钥派生函数包括防御知识攻击的机制,例如彩虹表和字典攻击,特别是" salt"和工作因素。现代KDF(如Argon2)也试图通过使用更适合任务的硬件来防止攻击者获得优势。

一般来说,这是如何使用的:

  1. 选择一个工作因素(您能负担的最大)
  2. 使用CSPRNG
  3. 生成盐
  4. 使用您选择的MAC密码,盐和工作因素生成加密密钥和KDF密码。
  5. 使用CSPRNG
  6. 生成IV(初始化向量)
  7. 使用生成的加密密钥加密要保护的数据。
  8. 使用生成的密钥计算加密邮件的MAC
  9. 序列化salt,工作因素,计算的MAC和加密数据。 (可选地,如果未修复这些标识符,则还应包括指示所选KDF,加密方案和MAC的标识符。)
  10. 您的加密邮件是步骤7中生成的序列化数据。获取任何错误的步骤(这很容易),您的加密代码可能会以可怕的方式破解。

    也许现在您已经了解了为什么要使用现有的库?

    注意:目前的最佳做法是使用AEAD(带有关联数据的经过身份验证的加密),而不是如上所述的encrypt-then-MAC。如果你有兴趣,请仔细阅读:我不打算在这里讨论。