CipherUtil { public static SaltedSecretKey createDerivedKey(SecretKey inputKey, byte[] inputSalt, CipherSpec outputCipherSpec) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException { return createDerivedKey(inputKey.getEncoded(), inputSalt, outputCipherSpec.getAlgorithm(), outputCipherSpec.getKeySize()); }  static synchronized void init(); static void enableUnlimitedStrength(); static byte[] createRandomArray(int size); static String createRandomAlphabeticString(int size); static SaltedSecretKey createDerivedKey(SecretKey inputKey, byte[] inputSalt, CipherSpec outputCipherSpec); static SaltedSecretKey createDerivedKey(byte[] inputKeyMaterial, byte[] inputSalt, String outputKeyAlgorithm, int outputKeySize); static SecretKey toSecretKey(byte[] secretKeyBytes, String algorithm); static SaltedSecretKey toSaltedSecretKey(byte[] secretKeyBytes, byte[] saltBytes, String algorithm); static SaltedSecretKey createMasterKey(String password); static SaltedSecretKey createMasterKey(String password, byte[] salt); static boolean isEncrypted(File file); static void encrypt(InputStream plaintextInputStream, OutputStream ciphertextOutputStream, List<CipherSpec> cipherSpecs,
			SaltedSecretKey masterKey); static byte[] encrypt(InputStream plaintextInputStream, List<CipherSpec> cipherSuites, SaltedSecretKey masterKey); static byte[] decrypt(InputStream fromInputStream, SaltedSecretKey masterKey); static KeyPair generateRsaKeyPair(); static X509Certificate generateSelfSignedCertificate(String commonName, KeyPair keyPair); static SSLContext createSSLContext(KeyStore keyStore, KeyStore trustStore);  }
@Test public void testCreateDerivedKeys() throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException { SaltedSecretKey masterKey = createDummyMasterKey(); CipherSpec cipherSpec = CipherSpecs.getCipherSpec(CipherSpecs.AES_128_GCM); byte[] derivedKeySalt1 = new byte[] { 1, 2, 3 }; byte[] derivedKeySalt2 = new byte[] { 1, 2, 3, 4 }; SaltedSecretKey derivedKey1 = CipherUtil.createDerivedKey(masterKey, derivedKeySalt1, cipherSpec); SaltedSecretKey derivedKey2 = CipherUtil.createDerivedKey(masterKey, derivedKeySalt2, cipherSpec); logger.log(Level.INFO, "- Derived key 1: "+StringUtil.toHex(derivedKey1.getEncoded())); logger.log(Level.INFO, " with salt: "+StringUtil.toHex(derivedKey1.getSalt())); logger.log(Level.INFO, "- Derived key 2: "+StringUtil.toHex(derivedKey2.getEncoded())); logger.log(Level.INFO, " with salt: "+StringUtil.toHex(derivedKey2.getSalt())); assertEquals(128/8, derivedKey1.getEncoded().length); assertEquals(128/8, derivedKey2.getEncoded().length); assertFalse(Arrays.equals(derivedKey1.getSalt(), derivedKey2.getSalt())); assertFalse(Arrays.equals(derivedKey1.getEncoded(), derivedKey2.getEncoded())); }