如何在 Java 中生成 384 位对称密钥大小?
How to generate a 384-bit Symmetric Key Size in Java?
我正在研究采用比 256 位(即 384)更大的对称密钥大小的密码?有没有一种方法可以使用 384 位的 KDF(或与此相关的任何其他东西)生成对称密钥。我尝试在 java 中使用 Key Generator
并使用 keyGenerator.init(384)
但它最多只支持 256 位。您认为我可以将 128 位对称密钥与从 Java 中的密钥生成器生成的 256 位对称密钥结合起来吗?我想避免必须尝试使用散列函数、对其进行大量迭代并尝试向其中添加我自己的随机盐。我知道这是一个不常见的问题,因为没有人会寻找 384 位对称密钥大小。我不是特别在寻找 KDF,只是一种生成随机对称密钥的简单而强大的方法。我的用例不涉及获取诸如用户密码之类的低熵值并将其作为密钥。
为什么不使用 SecretKeyFactory
class 和 PBKDF2WithHmacSHA384
算法。您可以在文档 here and here.
中找到详细信息
代码如下所示:
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");
最好在使用后清除 SecretKeySpec
和 SecretKey
,以避免将密钥暴露在堆转储中。从 Java 8 开始,没有简单的方法可以做到这一点,因为这两个接口的实现似乎没有实现接口 Destroyable
的方法 destroy()
。所以使用后用反射清除它们。
Do you think I could combine a 128-bit symmetric key with a 256 bit one generated from Key Generator in Java?
当然,对于 256 位和 128 位密钥,您只需使用 getEncoded()
检索字节,使用 Arrays.concat
将返回的两个 byte[]
合并为一个 byte[]
,然后对结果使用 new SecretKeySpec
。
I'd want to avoid having to try to use a hashing function, iterating it a lot, and trying to add my own random salts to it.
如果您有 256 位源 material,那么您可以使用 HMAC,将源 material 作为键,将任何信息(甚至是空消息)作为 HMAC 输入。如果您使用 SHA-384 - 正如已经建议的那样 - 那么输出将是一个整洁的 384 位键控 material 可以用作 SecretKeySpec
.
的输入
是的,将 PBKDF2 与 SHA-384、静态或什至空盐和单个迭代(迭代计数为 1)一起使用也可以。但这已经在 .
中提到了
I know this is an uncommon question as no one would be looking for a 384-bit symmetric key size.
嗯,有一个 SIV 操作模式,它欺骗并使用一个真正由两个连续密钥组成的密钥。所以即使是对称密码也有先例。
如果块密码或流密码直接使用 256 位密钥,那么我可能会称它为 snake-oil,因为即使量子计算成为现实,超过 256 位也没有任何意义。
最后,对称密码的密钥只是(伪)随机位 - 包含奇偶校验位的 DES 密钥是奇数位。因此,如果密码与 JCA 不兼容——即你真的不需要 SecretKey
对象实例——你可以只生成一个 48 字节的数组,用 SecureRandom
字节填充它并完成。
我正在研究采用比 256 位(即 384)更大的对称密钥大小的密码?有没有一种方法可以使用 384 位的 KDF(或与此相关的任何其他东西)生成对称密钥。我尝试在 java 中使用 Key Generator
并使用 keyGenerator.init(384)
但它最多只支持 256 位。您认为我可以将 128 位对称密钥与从 Java 中的密钥生成器生成的 256 位对称密钥结合起来吗?我想避免必须尝试使用散列函数、对其进行大量迭代并尝试向其中添加我自己的随机盐。我知道这是一个不常见的问题,因为没有人会寻找 384 位对称密钥大小。我不是特别在寻找 KDF,只是一种生成随机对称密钥的简单而强大的方法。我的用例不涉及获取诸如用户密码之类的低熵值并将其作为密钥。
为什么不使用 SecretKeyFactory
class 和 PBKDF2WithHmacSHA384
算法。您可以在文档 here and here.
代码如下所示:
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");
最好在使用后清除 SecretKeySpec
和 SecretKey
,以避免将密钥暴露在堆转储中。从 Java 8 开始,没有简单的方法可以做到这一点,因为这两个接口的实现似乎没有实现接口 Destroyable
的方法 destroy()
。所以使用后用反射清除它们。
Do you think I could combine a 128-bit symmetric key with a 256 bit one generated from Key Generator in Java?
当然,对于 256 位和 128 位密钥,您只需使用 getEncoded()
检索字节,使用 Arrays.concat
将返回的两个 byte[]
合并为一个 byte[]
,然后对结果使用 new SecretKeySpec
。
I'd want to avoid having to try to use a hashing function, iterating it a lot, and trying to add my own random salts to it.
如果您有 256 位源 material,那么您可以使用 HMAC,将源 material 作为键,将任何信息(甚至是空消息)作为 HMAC 输入。如果您使用 SHA-384 - 正如已经建议的那样 - 那么输出将是一个整洁的 384 位键控 material 可以用作 SecretKeySpec
.
是的,将 PBKDF2 与 SHA-384、静态或什至空盐和单个迭代(迭代计数为 1)一起使用也可以。但这已经在
I know this is an uncommon question as no one would be looking for a 384-bit symmetric key size.
嗯,有一个 SIV 操作模式,它欺骗并使用一个真正由两个连续密钥组成的密钥。所以即使是对称密码也有先例。
如果块密码或流密码直接使用 256 位密钥,那么我可能会称它为 snake-oil,因为即使量子计算成为现实,超过 256 位也没有任何意义。
最后,对称密码的密钥只是(伪)随机位 - 包含奇偶校验位的 DES 密钥是奇数位。因此,如果密码与 JCA 不兼容——即你真的不需要 SecretKey
对象实例——你可以只生成一个 48 字节的数组,用 SecureRandom
字节填充它并完成。