Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中生成384位对称密钥大小?_Java_Encryption_Cryptography_Aes_Encryption Symmetric - Fatal编程技术网

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

如何在Java中生成384位对称密钥大小?,java,encryption,cryptography,aes,encryption-symmetric,Java,Encryption,Cryptography,Aes,Encryption Symmetric,我正在研究一种密码,它的对称密钥比256位(384)大?有没有一种方法可以使用384位的KDF(或其他类似的东西)生成对称密钥。我曾尝试在java中使用密钥生成器,并尝试使用密钥生成器.init(384),但它最多只支持256位。您认为我可以将128位对称密钥与Java中密钥生成器生成的256位对称密钥结合起来吗?我希望避免尝试使用散列函数,多次迭代它,并尝试向其中添加我自己的随机盐。我知道这是一个不常见的问题,因为没有人会寻找384位对称密钥大小。我不是特别寻找KDF,只是一种生成随机对称密钥

我正在研究一种密码,它的对称密钥比256位(384)大?有没有一种方法可以使用384位的KDF(或其他类似的东西)生成对称密钥。我曾尝试在java中使用
密钥生成器
,并尝试使用
密钥生成器.init(384)
,但它最多只支持256位。您认为我可以将128位对称密钥与Java中密钥生成器生成的256位对称密钥结合起来吗?我希望避免尝试使用散列函数,多次迭代它,并尝试向其中添加我自己的随机盐。我知道这是一个不常见的问题,因为没有人会寻找384位对称密钥大小。我不是特别寻找KDF,只是一种生成随机对称密钥的简单而强大的方法。我的用例不涉及获取像用户密码这样的低熵信息并将其作为密钥

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

代码如下所示:

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
,以避免使用堆转储暴露密钥。对于Java8,没有简单的方法可以做到这一点,因为这两个接口的实现似乎没有实现接口
Destroyable
的方法
destroy()
。因此,使用后使用反射清除它们

您认为我可以将128位对称密钥与Java中密钥生成器生成的256位对称密钥结合起来吗

当然,对于256位和128位密钥,您只需使用
getEncoded()
检索字节,使用
Arrays.concat将返回的两个
byte[]
组合成一个
byte[]
,然后对结果使用
new SecretKeySpec

我希望避免尝试使用散列函数,多次迭代它,并尝试向其中添加我自己的随机盐

如果您有256位的源材料,那么您可以使用HMAC,源材料作为键,任何信息(甚至是空消息)作为HMAC输入。如果您使用SHA-384(如前所述),那么输出将是一个整洁的384位键控材料,可以用作
SecretKeySpec
的输入

是的,在SHA-384中使用PBKDF2,一个静态的甚至是空的salt和一次迭代(迭代计数为1)也可以工作。但这已经在文章中提到了

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

有一种SIV操作模式,它欺骗并使用一个由两个连续键组成的键。因此,即使是对称密码也有先例

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



最后,对称密码的密钥是简单的(伪)随机位,其中DES密钥包括奇偶校验位,奇偶校验位除外。因此,如果密码与JCA不兼容-即,您实际上不需要
SecretKey
对象实例-您只需生成一个48字节的数组,用
SecureRandom
字节填充它就可以了。

没有理由使用特定的哈希函数,PBKDF2能够用任何通用的安全Hmac生成384位的密钥材料。@James K Polk这样做是否更好:
SecretKeyFactory.getInstance(“PBKDF2WithHmac”)
。我不明白为什么会更好。PBKDF2用于从密码或类似的低熵源生成密钥位。如果您只需要一个随机的384位密钥,请使用类似于
byte[]key=new byte[384/8]的内容;新SecureRandom().nextBytes(密钥)
@JamesKPolk我会使用PBKDF2而不眨眼,但我会确保我的
char[]
的字节值只包含最低有效位,当然也要确保
char[]
和之前的
byte[]
在使用后会被销毁。Saptarshi,你特意销毁了钥匙,但是在这种情况下,当然也需要销毁原始材料。另外,您还生成了一个强随机salt(为什么?),并且没有指定迭代计数(值为1)。当然,这很好。但是,如果你把答案放在问题的标题中,我建议你不要把这样的建议放在问题的标题中。KeyGenerator是特定于算法的:如果注册提供商不支持你的算法,那么使用KeyGenerator没有多大意义。实际上,整个JCA都是基于提供者体系结构的,如果您自己开发的密码类不能使用
密钥做任何事情,那么创建
java.security.Key
的实例对您没有多大好处。为什么只需要一次迭代?我认为几次迭代会更好地加强密钥。似乎我误解了,也没有真正理解“熵”的概念。我不需要任何用户输入,比如创建密钥的密码。我只需要一个用于对称加密算法(如AES)的随机密钥。使用
Secure Random
生成密钥比使用PBKDF具有更高的熵。我现在明白了,提供密码是为了在必要时使用,比如创建用户密码。从我的用例来看,我认为生成一个随机的48字节数组更有意义。如果您能澄清空salt和迭代计数为1的原因,那就太好了。我认为迭代次数应该是几千次,这取决于系统的能力,而且为了安全起见,salt必须是随机的。PBKDF2不是这么说的吗?或者在这个特定问题的上下文中不需要它?确切地说,您将使用基于密码的密钥派生