Ama*_*man 6 java encryption aes
在多线程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
Run Code Online (Sandbox Code Playgroud)
解密:
Cipher decrypter = Cipher.getInstance(algorithm, new BouncyCastleProvider());
IvParameterSpec ivSpec = readIvParamSpec(decrypter.getBlockSize(), is);
decrypter.init(Cipher.DECRYPT_MODE, key, ivSpec);
//.. decrypt the data
Run Code Online (Sandbox Code Playgroud)
根据我们的理解,最好使用随机IV进行加密而不是静态/固定IV.为此,我们使用SecureRandom API生成IV.随机IV在开始时保存在加密文件中.
SecureRandom random = new SecureRandom();
byte[] iv = new byte[ivSizeBytes];
random.nextBytes(iv);
new IvParameterSpec(iv);
Run Code Online (Sandbox Code Playgroud)
我的问题是,因为我使用随机IV进行每次加密,我是否需要为所有调用调用Cipher.getInstance()和Cipher.Init()?为了提高性能,这些只能在类初始化期间调用一次,然后重用单个密码实例来加密和解密数据吗?
提前致谢!
是的,您需要Cipher为每个线程使用不同的实例,因为它们是有状态的.如果不这样做,那么线程可以破坏其他线程的密文.
假设我们有两个线程t1,t2它们想要加密两个明文p1_1 | p1_2和p2_1 | p2_1(在块边界上分开).我们以CBC为例:
time........................................................................
root 1. init with IV
t1 2. E(p1_1 XOR IV) = c1_1 4. E(p1_2 XOR c2_1) = c1_2
t2 3. E(p2_1 XOR c1_1) = c2_1 5. E(p2_2 XOR c1_2) = c2_2
Run Code Online (Sandbox Code Playgroud)
c1_1没关系,但是c2_1不行,因为状态from t1用于启动加密.好像加密是用c1_1IV 初始化的.
此示例仅适用于CBC模式,但其他操作模式类似.如果我们假设加密只是按块进行,那么你可以以线程安全的方式使用ECB模式,但这只是一种幻觉,因为你不能确定实现只是按块处理内部状态而不是按字节.
我的问题是,由于我对每种加密使用随机IV,是否需要为所有调用调用Cipher.getInstance()和Cipher.Init()?
只要不在线程之间共享它们,就可以重用Cipher实例。如Artjom所述,密码实例是有状态的。它们既存储IV,又存储最后的密文(用作CBC模式加密的下一个向量),还可能存储一些缓冲的明文。将该状态与来自不同线程的输入混合会导致混乱。
由于每个文件加密都需要一个新的随机数,因此您确实需要init在调用doFinal方法后再次调用。Init并不是那么重量级;可能需要一点性能的一件事是AES的子密钥派生,但通常这不是大问题。
注意,尽管执行加密和解密可能是比较繁重的操作,但是实例本身包含很少的状态,getInstance()并且init是相对轻量级的操作。因此,创建多个Cipher实例(可能使用相同的键)对于多个线程来说是很好的。
重新创建BouncyCastleProvider多次是一个非常糟糕的主意,即使它可能在下面使用某种单例。但基本上,您不需要仅Java的 Bouncy Castle实现。Oracle可能会使用AES-NI内部函数,而这些函数将直接使用兼容处理器上的AES-NI指令集。它将在Bouncy Castle周围绕圈-预计加速约7到13倍(!)。
| 归档时间: |
|
| 查看次数: |
1568 次 |
| 最近记录: |