private void testEncrypt(byte[] originalData, List<CipherSpec> cipherSpecs) throws CipherException { SaltedSecretKey masterKey = createDummyMasterKey(); byte[] ciphertext = CipherUtil.encrypt( new ByteArrayInputStream(originalData), cipherSpecs, masterKey ); byte[] plaintext = CipherUtil.decrypt(new ByteArrayInputStream(ciphertext), masterKey); assertFalse(Arrays.equals(originalData, ciphertext)); assertTrue(Arrays.equals(originalData, plaintext)); }
@Test public void testEncryptShortArrayAes128Gcm() throws Exception { testEncrypt( new byte[] { 1, 2, 3, 4 }, Arrays.asList(new CipherSpec[] { CipherSpecs.getCipherSpec(CipherSpecs.AES_128_GCM) }) ); }
@Test(expected = Exception.class) public void testIntegrityTwofishGcmCiphertext() throws Exception { SaltedSecretKey masterKey = createDummyMasterKey(); byte[] originalPlaintext = TestFileUtil.createRandomArray(50); byte[] ciphertext = CipherUtil.encrypt( new ByteArrayInputStream(originalPlaintext), Arrays.asList(CipherSpecs.getCipherSpec(CipherSpecs.TWOFISH_128_GCM)), masterKey ); // Alter ciphertext (after header!); ciphertext starts after 75 bytes ciphertext[80] = (byte) (ciphertext[80] ^ 0x01); byte[] plaintext = CipherUtil.decrypt(new ByteArrayInputStream(ciphertext), masterKey); System.out.println(StringUtil.toHex(originalPlaintext)); System.out.println(StringUtil.toHex(plaintext)); fail("TEST FAILED: Ciphertext was altered without exception."); }
@Test public void testEncryptShortArrayAes128Twofish128() throws Exception { testEncrypt( new byte[] { 1, 2, 3, 4 }, Arrays.asList(new CipherSpec[] { CipherSpecs.getCipherSpec(CipherSpecs.AES_128_GCM), CipherSpecs.getCipherSpec(CipherSpecs.TWOFISH_128_GCM) }) ); }
@Test(expected = CipherException.class) public void testIntegrityAesGcmCiphertext() throws Exception { SaltedSecretKey masterKey = createDummyMasterKey(); byte[] originalPlaintext = TestFileUtil.createRandomArray(50); byte[] ciphertext = CipherUtil.encrypt( new ByteArrayInputStream(originalPlaintext), Arrays.asList(CipherSpecs.getCipherSpec(CipherSpecs.AES_128_GCM)), masterKey ); // Alter ciphertext (after header!); ciphertext starts after 75 bytes ciphertext[80] = (byte) (ciphertext[80] ^ 0x01); ciphertext[81] = (byte) (ciphertext[81] ^ 0x02); ciphertext[82] = (byte) (ciphertext[82] ^ 0x03); CipherUtil.decrypt(new ByteArrayInputStream(ciphertext), masterKey); fail("TEST FAILED: Ciphertext was altered without exception."); }
@Test public void testEncryptLongArrayAes128Gcm() throws Exception { testEncrypt( TestFileUtil.createRandomArray(1024*1024), Arrays.asList(new CipherSpec[] { CipherSpecs.getCipherSpec(CipherSpecs.AES_128_GCM) }) ); }
@Test(expected = Exception.class) public void testIntegrityHeaderVersion() throws Exception { SaltedSecretKey masterKey = createDummyMasterKey(); byte[] originalPlaintext = TestFileUtil.createRandomArray(50); byte[] ciphertext = CipherUtil.encrypt( new ByteArrayInputStream(originalPlaintext), Arrays.asList(CipherSpecs.getCipherSpec(CipherSpecs.AES_128_GCM)), masterKey ); // Alter header VERSION ciphertext[4] = (byte) 0xff; byte[] plaintext = CipherUtil.decrypt(new ByteArrayInputStream(ciphertext), masterKey); System.out.println(StringUtil.toHex(originalPlaintext)); System.out.println(StringUtil.toHex(plaintext)); fail("TEST FAILED: Ciphertext was altered without exception."); }
@Test public void testEncryptLongArrayAes258Twofish256UnlimitedStrength() throws Exception { testEncrypt( TestFileUtil.createRandomArray(1024*1024), Arrays.asList(new CipherSpec[] { CipherSpecs.getCipherSpec(CipherSpecs.AES_256_GCM), CipherSpecs.getCipherSpec(CipherSpecs.TWOFISH_256_GCM) }) ); }
@Test(expected = Exception.class) public void testIntegrityHeaderMagic() throws Exception { SaltedSecretKey masterKey = createDummyMasterKey(); byte[] originalPlaintext = TestFileUtil.createRandomArray(50); byte[] ciphertext = CipherUtil.encrypt( new ByteArrayInputStream(originalPlaintext), Arrays.asList(CipherSpecs.getCipherSpec(CipherSpecs.AES_128_GCM)), masterKey ); // Alter header MAGIC BYTES ciphertext[0] = 0x12; ciphertext[1] = 0x34; byte[] plaintext = CipherUtil.decrypt(new ByteArrayInputStream(ciphertext), masterKey); System.out.println(StringUtil.toHex(originalPlaintext)); System.out.println(StringUtil.toHex(plaintext)); fail("TEST FAILED: Ciphertext was altered without exception."); }
@Test public void testEncryptLongArrayAes128Twofish128() throws Exception { testEncrypt( TestFileUtil.createRandomArray(1024*1024), Arrays.asList(new CipherSpec[] { CipherSpecs.getCipherSpec(CipherSpecs.AES_128_GCM), CipherSpecs.getCipherSpec(CipherSpecs.TWOFISH_128_GCM) }) ); }
@Test(expected = Exception.class) public void testIntegrityHeaderCipherSalt() throws Exception { SaltedSecretKey masterKey = createDummyMasterKey(); byte[] originalPlaintext = TestFileUtil.createRandomArray(50); byte[] ciphertext = CipherUtil.encrypt( new ByteArrayInputStream(originalPlaintext), Arrays.asList(CipherSpecs.getCipherSpec(CipherSpecs.AES_128_GCM)), masterKey ); // Alter header CIPHER SALT ciphertext[19] = (byte) 0xff; ciphertext[20] = (byte) 0xff; ciphertext[21] = (byte) 0xff; byte[] plaintext = CipherUtil.decrypt(new ByteArrayInputStream(ciphertext), masterKey); System.out.println(StringUtil.toHex(originalPlaintext)); System.out.println(StringUtil.toHex(plaintext)); fail("TEST FAILED: Ciphertext was altered without exception."); }
@Test(expected = Exception.class) public void testIntegrityHeaderCipherIV() throws Exception { SaltedSecretKey masterKey = createDummyMasterKey(); byte[] originalPlaintext = TestFileUtil.createRandomArray(50); byte[] ciphertext = CipherUtil.encrypt( new ByteArrayInputStream(originalPlaintext), Arrays.asList(CipherSpecs.getCipherSpec(CipherSpecs.AES_128_GCM)), masterKey ); // Alter header CIPHER SALT ciphertext[32] = (byte) 0xff; ciphertext[33] = (byte) 0xff; ciphertext[34] = (byte) 0xff; byte[] plaintext = CipherUtil.decrypt(new ByteArrayInputStream(ciphertext), masterKey); System.out.println(StringUtil.toHex(originalPlaintext)); System.out.println(StringUtil.toHex(plaintext)); fail("TEST FAILED: Ciphertext was altered without exception."); }
@Test(expected = Exception.class) public void testIntegrityHeaderCipherSpecId() throws Exception { SaltedSecretKey masterKey = createDummyMasterKey(); byte[] originalPlaintext = TestFileUtil.createRandomArray(50); byte[] ciphertext = CipherUtil.encrypt( new ByteArrayInputStream(originalPlaintext), Arrays.asList(CipherSpecs.getCipherSpec(CipherSpecs.AES_128_GCM)), masterKey ); assertEquals(CipherSpecs.AES_128_GCM, ciphertext[18]); // If this fails, fix test! // Alter header CIPHER SPEC ID ciphertext[18] = (byte) 0xff; byte[] plaintext = CipherUtil.decrypt(new ByteArrayInputStream(ciphertext), masterKey); System.out.println(StringUtil.toHex(originalPlaintext)); System.out.println(StringUtil.toHex(plaintext)); fail("TEST FAILED: Ciphertext was altered without exception."); }
@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())); }