我有包含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