CipherSession { public SaltedSecretKey getReadSecretKey(CipherSpec cipherSpec, byte[] salt) throws Exception { CipherSpecWithSalt cipherSpecWithSalt = new CipherSpecWithSalt(cipherSpec, salt); SecretKeyCacheEntry secretKeyCacheEntry = secretKeyReadCache.get(cipherSpecWithSalt); if (secretKeyCacheEntry != null) { logger.log(Level.FINE, "- Using CACHED READ secret key " + secretKeyCacheEntry.getSaltedSecretKey().getAlgorithm() + ", with salt " + StringUtil.toHex(salt)); return secretKeyCacheEntry.getSaltedSecretKey(); } else { if (secretKeyReadCache.size() >= secretKeyReadCacheSize) { CipherSpecWithSalt firstKey = secretKeyReadCache.keySet().iterator().next(); secretKeyReadCache.remove(firstKey); logger.log(Level.FINE, "- Removed oldest READ secret key from cache."); } SaltedSecretKey saltedSecretKey = createSaltedSecretKey(cipherSpec, salt); secretKeyCacheEntry = new SecretKeyCacheEntry(saltedSecretKey); secretKeyReadCache.put(cipherSpecWithSalt, secretKeyCacheEntry); logger.log(Level.FINE, "- Created NEW READ secret key " + secretKeyCacheEntry.getSaltedSecretKey().getAlgorithm() + ", and added to cache, with salt " + StringUtil.toHex(salt)); 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 testCipherSessionReadKeyCacheSizeOfThree() throws Exception { SaltedSecretKey masterKey = createDummyMasterKey(); CipherSession cipherSession = new CipherSession(masterKey, 2, 999); CipherSpec cipherSpecAes128 = CipherSpecs.getCipherSpec(CipherSpecs.AES_128_GCM); byte[] readKeySalt1 = CipherUtil.createRandomArray(cipherSpecAes128.getKeySize()); byte[] readKeySalt2 = CipherUtil.createRandomArray(cipherSpecAes128.getKeySize()); byte[] readKeySalt3 = CipherUtil.createRandomArray(cipherSpecAes128.getKeySize()); SaltedSecretKey readSecretKey1Aes128 = cipherSession.getReadSecretKey(cipherSpecAes128, readKeySalt1); SaltedSecretKey readSecretKey2Aes128 = cipherSession.getReadSecretKey(cipherSpecAes128, readKeySalt2); SaltedSecretKey readSecretKey3Aes128 = cipherSession.getReadSecretKey(cipherSpecAes128, readKeySalt3); assertNotSame(readSecretKey1Aes128, readSecretKey2Aes128); assertNotSame(readSecretKey1Aes128, readSecretKey3Aes128); assertNotSame(readSecretKey2Aes128, readSecretKey3Aes128); }