【发布时间】:2020-10-06 05:13:43
【问题描述】:
给定一个任意 Java 字节数组,例如 1024 字节数组,我想派生一个 AES-256 位密钥。该数组是从 ECHD 通过javax.crypto.KeyAgreement 使用byte[] secret = keyAgreement.generateSecret() 生成的
我目前的解决方案是将输入字节数组视为密码。使用 PBKDF2 密钥派生函数输入数组作为密码和盐,如下所示。
更新:我已将 UTF-8 设置为编码以解决 cmets 和答案中指出的问题。
private byte[] deriveAes256bitKey(byte[] secret)
throws NoSuchAlgorithmException, InvalidKeySpecException {
var secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
var password = new String(secret, UTF_8).toCharArray();
var keySpec = new PBEKeySpec(password, secret, 1024, 256);
return secretKeyFactory.generateSecret(keySpec).getEncoded();
}
有没有更好的方法在 Java 中获取字节数组并将其转换为 AES-256 位密钥?
【问题讨论】:
-
你的数组有多少熵?您应该使用已建立的密钥派生函数 (KDF)。哪一个取决于数组中有多少熵,但我相信 Java 中唯一可用的好的熵是 PBKDF2。 PBKDF2 包含额外的安全功能,以增强密码等低熵值的安全边际。但是,如果您有一个全熵数组,这些功能不会伤害您。正如一个答案指出的那样,您不应该以您正在做的方式将数组转换为字符串。您应该改为 base64 对其进行编码。如果你有 Bouncycastle 库,你还有其他的 KDF 选项。
-
一种选择是使用 PBKDF 使用单次迭代。但由于处理 Java PBKDF API 的奇怪字符串,我不建议这样做。
-
@MaartenBodewes 我更新了上面的示例代码以使用 UTF_8 对奇怪的字符串处理没有影响吗?您能否详细说明奇怪的字符串处理的影响是什么?
标签: java security cryptography aes jce