如何在Java中生成384位对称密钥大小?

时间:2019-07-15 14:04:53

标签: java encryption cryptography aes encryption-symmetric

我正在研究一种密码,该密码的对称密钥大小大于256位(即384位)?有没有一种方法可以使用384位的KDF之类的东西来生成对称密钥。我尝试在Java中使用Key Generator,并做了keyGenerator.init(384),但它最多支持256位。您认为我可以将128位对称密钥与从Java密钥生成器生成的256位密钥组合在一起吗?我想避免不得不尝试使用哈希函数,对其进行大量迭代以及尝试向其中添加自己的随机盐。我知道这是一个不常见的问题,因为没有人会寻找384位对称密钥大小。我并不是特别在寻找KDF,它只是一种简单而强大的生成随机对称密钥的方法。我的用例不涉及获取诸如用户密码之类的低熵的东西并将其作为密钥。

2 个答案:

答案 0 :(得分:2)

  

您认为我可以将128位对称密钥与从Java密钥生成器生成的256位对称密钥相结合吗?

当然,您只需使用getEncoded()来获取256位和128位密钥的字节,使用byte[]将返回的两个byte[]合并为一个Arrays.concat,然后在结果上使用new SecretKeySpec

  

我希望避免尝试使用哈希函数,对其进行大量迭代并尝试向其中添加自己的随机盐。

如果您将使用256位源材料,则可以将HMAC与源材料一起用作键,并将任何信息(甚至是空消息)用作HMAC输入。如果您已经按照建议使用SHA-384,那么输出将是整齐的384位密钥材料,可用作SecretKeySpec的输入。

是的,使用带有SHA-384的PBKDF2,也可以使用静态甚至空盐和单次迭代(迭代计数为1)。但这已经在the other answer by Saptarshi中提到过。

  

我知道这是一个不常见的问题,因为没有人会寻找384位对称密钥大小。

好吧,有一种SIV操作模式可以欺骗并使用真正由两个连续键组成的键。因此,即使对于对称密码也有先例。

如果块或流密码直接使用256位密钥,那么我可能会称其为蛇油,因为即使量子计算成为现实,超过256位也没有意义。


最后,对称密码的秘密密钥就是简单的(伪)随机位-包含奇偶校验位的DES密钥。因此,如果该密码与JCA不兼容-即您确实不需要SecretKey对象实例-您可以生成一个48字节的数组,并用SecureRandom个字节填充并完成。

答案 1 :(得分:1)

为什么不将SecretKeyFactory类与PBKDF2WithHmacSHA384算法一起使用。您可以在文档herehere中找到详细信息。

代码如下:

SecureRandom random = SecureRandom.getInstanceStrong();
byte[] salt = new byte[32];
random.nextBytes(salt);
PBEKeySpec keySpec = new PBEKeySpec(password, salt, iterations, 
   keyLength);
SecretKeyFactory keyFactory = 
SecretKeyFactory.getInstance("PBKDF2WithHmacSHA384");
SecretKey secretKey = keyFactory.generateSecret(keySpec);
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(),
    "AES");

最好在使用后清除SecretKeySpecSecretKey,以避免用堆转储公开键。从Java 8开始,没有容易做到的方法,因为这两个接口的实现似乎尚未实现接口destroy()的方法Destroyable。因此,使用后请使用反射将其清除。