gpt4 book ai didi

java - AES 256 解密 - IV 可以安全共享吗?

转载 作者:搜寻专家 更新时间:2023-11-01 03:04:48 28 4
gpt4 key购买 nike

正在关注 this question及其答案,我正在创建一个给定密码字符串的应用程序,将转换明文并将其密文、生成的盐和初始化 vector 存储在文本文件中。

在下面的代码中:

public String decrypt(CryptGroup cp) throws Exception {
String plaintext = null;
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password, cp.getSalt(), ITERATIONS, KEY_SIZE);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(cp.getIv()));
plaintext = new String(cipher.doFinal(cp.getCipher()), "UTF-8");

return plaintext;
}

public CryptGroup encrypt(String plainText) throws Exception {
byte[] salt = generateSalt();
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_SIZE);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] ciphertext = cipher.doFinal(plainText.getBytes("UTF-8"));

return new CryptGroup(ciphertext, salt, iv);
}

CryptGroup 对象包含这 3 个参数(密文、salt、iv:字节数组)。

存储初始化 vector 安全吗?

那个问题的答案很明确,salt不需要保密,显然密文也可以,但是iv参数呢?

编辑如果共享不安全,是否可以单独从盐中取回原始 iv?

最佳答案

是的,IV 可以是公共(public)信息。您可以将计算用作 IV,只要您从不两次使用键和 IV 的组合即可。换句话说,您应该能够只共享盐,只要您为每次加密更改盐

此外,对于 CBC,要求 IV 对于攻击者来说“看起来像是随机的”,尤其是当用于相同的 key 时。所以通常的方案是使用 PBKDF2 的一些输出作为 IV 数据。这些特定位当然也不应该用于创建 key ,但可以拆分输出大小。

这有一些缺点,因为如果您请求超过 160 位的信息(对于 SHA1),PBKDF2 将使用更多轮次。因此,您可以连接 PBKDF2 的输出和一个计数器(0 代表 key ,1 代表 IV)并使用例如SHA256 生成 128 位 key (最左边 16 个字节)和 128 位 IV(最右边 16 个字节)。


让我们探索这个方案的一些变体:

  • 您还可以使用 SHA-512 等不同的散列来创建更大的输出并将其拆分以获得 key 和 IV,但请注意,这样的函数可能并非随处可用。 Java 8 应该有 "PBKDF2WithHmacSHA512" (对于 SecretKeyFactory )。

  • 您还可以生成一个 PBKDF2 输出,然后使用 HKDF 或 HKDF-Expand 派生 key 和 IV。问题是 HKDF/HKDF-Expand 不能直接从 Java 获得。 Bouncy CaSTLe 确实有那个方法,因为我发送了各种 KDF 的实现。

  • 还有一种方法是使用 SecureRandom 生成新的 IV,但在这种情况下,您需要同时存储盐和 IV。如果您需要使用同一 key 加密多条消息,这可能很有用。在这种情况下,您可以为每条单独的消息生成并存储一个 IV。如果您能够简单地存储 16 个额外字节,这是一个很好的方法。

  • 原则上,只要您从不重复使用相同的 key (即从不重复使用相同的密码/salt 组合),您也可以使用全零 IV。但是,在这种情况下,您可能希望使用 AES-256 来避免多目标攻击。

关于java - AES 256 解密 - IV 可以安全共享吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26369350/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com