我有包含Java JCA密码和消息摘要对象的实例不可变加密器辅助对象池:这个加密代码线程安全吗?
AlgorithmInstance(Cipher encCipher, Cipher decCipher, MessageDigest digest) { ... }
private BlockingQueue<AlgorithmInstance> pool = new ArrayBlockingQueue<AlgorithmInstance>(poolSize);
不同的线程在我的应用程序,需要加密或解密,通过访问池争AlgorithmInstance对象。每个线程使用它们进行加密或解密,然后在完成后将它们返回给池。线程不会在任何JCA对象上同步,因为没有并发访问。解密工作方式大致相同。
public byte[] encryptMessage(byte data[]) { ...
try {
AlgorithmInstance inst = pool.take();
inst.digest.reset();
byte[] digest = inst.digest.digest(message);
inst.encryptCipher.init(Cipher.ENCRYPT_MODE, m_currentKey, ivParams);
inst.encryptCipher.doFinal(messageBuffer);
}
finally {
pool.put(inst)
}
}
这项工程99.99%的时间;和100%的时间在单元测试。然而,一旦进入蓝色月亮,我会收到一条消息,其计算的摘要不正确 - 通常这表示消息篡改或网络错误;但是发送者和接收者在同一台机器上(在不同的进程中)。
问:是否有一个密码或文摘一些内部状态,这可以从内存一致性效应的影响 - 我在一个2核心的Windows中,所以我看不出我甚至可以从内存中遭受的一致性效果。我重新初始化密码并消化每个呼叫,所以它应该没有关系。
问:有没有什么办法可以结束与填充模式,有时根据消息长度失败?解密器和加密器使用完全相同的算法(AES/CBC/Pkcs5Padding + SHA-256,密钥大小为128)。
答案1:不是我能看到的。答案2:No. – 2010-11-24 00:50:05
我的感觉是它在GC或者密码/摘要中的一些共享缓冲区有一些副作用;或者@Rook表示我错误地使用了它。它再次发生,文摘完全不同,不仅仅是几个不同点。绝对不知道。 – Justin 2010-11-24 01:30:12
你有没有理由把它们放在一起?它是否真的提供性能优势?我会猜想创建cyper对象不会很昂贵。 – CodesInChaos 2011-01-11 20:58:17