CipherSession { public SaltedSecretKey getWriteSecretKey(CipherSpec cipherSpec) throws Exception { SecretKeyCacheEntry secretKeyCacheEntry = secretKeyWriteCache.get(cipherSpec); if (secretKeyCacheEntry != null && secretKeyCacheEntry.getUseCount() >= secretKeyWriteReuseCount) { logger.log(Level.FINE, "- Removed WRITE secret key from cache, because it was used " + secretKeyCacheEntry.getUseCount() + " times."); secretKeyWriteCache.remove(cipherSpec); secretKeyCacheEntry = null; } if (secretKeyCacheEntry != null) { secretKeyCacheEntry.increaseUseCount(); logger.log(Level.FINE, "- Using CACHED WRITE secret key " + secretKeyCacheEntry.getSaltedSecretKey().getAlgorithm() + ", with salt " + StringUtil.toHex(secretKeyCacheEntry.getSaltedSecretKey().getSalt())); return secretKeyCacheEntry.getSaltedSecretKey(); } else { SaltedSecretKey saltedSecretKey = createSaltedSecretKey(cipherSpec); secretKeyCacheEntry = new SecretKeyCacheEntry(saltedSecretKey); secretKeyWriteCache.put(cipherSpec, secretKeyCacheEntry); logger.log(Level.FINE, "- Created NEW WRITE secret key " + secretKeyCacheEntry.getSaltedSecretKey().getAlgorithm() + ", and added to cache, with salt " + StringUtil.toHex(saltedSecretKey.getSalt())); return saltedSecretKey; } } CipherSession(SaltedSecretKey masterKey);  CipherSession(SaltedSecretKey masterKey, int secretKeyReadCacheSize, int secretKeyWriteReuseCount); SecretKey getMasterKey(); SaltedSecretKey getWriteSecretKey(CipherSpec cipherSpec); SaltedSecretKey getReadSecretKey(CipherSpec cipherSpec, byte[] salt);  }
@Test public void testCipherSessionWriteKeyReuseCountOfTwo() throws Exception { SaltedSecretKey masterKey = createDummyMasterKey(); CipherSession cipherSession = new CipherSession(masterKey, 999, 2); CipherSpec cipherSpecAes128 = CipherSpecs.getCipherSpec(CipherSpecs.AES_128_GCM); CipherSpec cipherSpecTwofish128 = CipherSpecs.getCipherSpec(CipherSpecs.TWOFISH_128_GCM); SaltedSecretKey writeSecretKey1Aes128 = cipherSession.getWriteSecretKey(cipherSpecAes128); SaltedSecretKey writeSecretKey2Aes128 = cipherSession.getWriteSecretKey(cipherSpecAes128); SaltedSecretKey writeSecretKey3Aes128 = cipherSession.getWriteSecretKey(cipherSpecAes128); SaltedSecretKey writeSecretKey1Twofish128 = cipherSession.getWriteSecretKey(cipherSpecTwofish128); SaltedSecretKey writeSecretKey2Twofish128 = cipherSession.getWriteSecretKey(cipherSpecTwofish128); SaltedSecretKey writeSecretKey3Twofish128 = cipherSession.getWriteSecretKey(cipherSpecTwofish128); assertEquals(writeSecretKey1Aes128, writeSecretKey2Aes128); assertNotSame(writeSecretKey1Aes128, writeSecretKey3Aes128); assertEquals(writeSecretKey1Twofish128, writeSecretKey2Twofish128); assertNotSame(writeSecretKey1Twofish128, writeSecretKey3Twofish128); assertNotSame(writeSecretKey1Aes128, writeSecretKey1Twofish128); }