gpt4 book ai didi

java - Cipher.getInstance() 和 Cipher.getInit() 用于 AES 加密的随机 IV 情况下的每条消息

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:54:48 31 4
gpt4 key购买 nike

在多线程 Java 应用程序中,我们使用 AES-256 对磁盘文件进行加密和解密。请注意,多个线程可以同时调用不同文件的加密和解密方法。

加密:

Cipher encrypter = Cipher.getInstance(algorithm, new BouncyCastleProvider());
IvParameterSpec ivSpec = getIvParamSpec(encrypter.getBlockSize());
encrypter.init(Cipher.ENCRYPT_MODE, key, ivSpec);
//..encrypt the data

解密:

Cipher decrypter = Cipher.getInstance(algorithm, new BouncyCastleProvider());
IvParameterSpec ivSpec = readIvParamSpec(decrypter.getBlockSize(), is);
decrypter.init(Cipher.DECRYPT_MODE, key, ivSpec);
//.. decrypt the data

根据我们的理解,最好使用随机 IV 进行加密,而不是使用静态/固定 IV。为此,我们使用 SecureRandom API 生成 IV。随机 IV 在开始时保存在加密文件中。

SecureRandom random = new SecureRandom();
byte[] iv = new byte[ivSizeBytes];
random.nextBytes(iv);
new IvParameterSpec(iv);

我的问题是,由于我对每次加密都使用随机 IV,我是否需要为所有调用调用 Cipher.getInstance() 和 Cipher.Init()?为了提高性能,是否可以在类初始化期间仅调用一次,然后重用各个密码实例来加密和解密数据?

提前致谢!

最佳答案

My question is, since I am using random IV for each encryption, do I need to call Cipher.getInstance() and Cipher.Init() for all the calls?

只要不在线程之间共享 Cipher 实例,就可以重用它们。正如 Artjom 提到的,Cipher 实例是有状态的。它们既存储 IV,也存储最后的密文(用作 CBC 模式加密的下一个 vector )和可能的一些缓冲明文。将该状态与来自不同线程的输入混合在一起会导致困惑。

由于每个文件加密都需要一个新的随机数,因此您需要在调用 doFinal 方法后再次调用 init。 Init 没有那么重量级;可能需要一点性能的一件事是 AES 的子 key 派生,但通常这不是什么大问题。

请注意,虽然执行加密和解密可能是相对重量级的操作,但实例本身包含的状态很少,getInstance()init 是相对轻量级的操作.因此,创建更多的 Cipher 实例(可能使用相同的 key )对多线程来说没问题。


多次重新创建 BouncyCaSTLeProvider 是一个非常糟糕的主意,即使它可能在底层使用了某种单例。但基本上您不需要仅 Java Bouncy CaSTLe 实现。 Oracle 可能会使用 AES-NI 内在函数,这些函数将直接在兼容处理器上使用 AES-NI 指令集。这将围绕 Bouncy CaSTLe 运行 - 预计加速大约 7 到 13 倍(!)。

关于java - Cipher.getInstance() 和 Cipher.getInit() 用于 AES 加密的随机 IV 情况下的每条消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43989519/

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