/* See LICENSE for licensing and NOTICE for copyright. */ package org.cryptacular.bean; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.security.KeyStore; import javax.crypto.SecretKey; import org.cryptacular.FailListener; import org.cryptacular.generator.sp80038d.CounterNonce; import org.cryptacular.io.FileResource; import org.cryptacular.spec.AEADBlockCipherSpec; import org.cryptacular.util.ByteUtil; import org.cryptacular.util.StreamUtil; import org.testng.annotations.DataProvider; import org.testng.annotations.Listeners; import org.testng.annotations.Test; import static org.testng.Assert.assertEquals; /** * Unit test for {@link AEADBlockCipherBean}. * * @author Middleware Services */ @Listeners(FailListener.class) public class AEADBlockCipherBeanTest { @DataProvider(name = "test-arrays") public Object[][] getTestArrays() { return new Object[][] { new Object[] { // Plaintext is NOT multiple of block size "Able was I ere I saw elba.", "AES/GCM", }, // Plaintext is multiple of block size new Object[] { "Four score and seven years ago, our forefathers ", "Twofish/CCM", }, // OCB new Object[] { "Have you passed through this night?", "Twofish/OCB", }, // EAX new Object[] { "I went to the woods because I wished to live deliberately, to front only the essential facts of life", "AES/EAX", }, }; } @DataProvider(name = "test-streams") public Object[][] getTestStreams() { return new Object[][] { new Object[] { "src/test/resources/plaintexts/lorem-5000.txt", "Twofish/GCM", }, new Object[] { "src/test/resources/plaintexts/lorem-1200.txt", "AES/OCB", }, new Object[] { "src/test/resources/plaintexts/lorem-1200.txt", "AES/EAX", }, }; } @Test(dataProvider = "test-arrays") public void testEncryptDecryptArray(final String input, final String cipherSpecString) throws Exception { final AEADBlockCipherBean cipherBean = new AEADBlockCipherBean(); final AEADBlockCipherSpec cipherSpec = AEADBlockCipherSpec.parse(cipherSpecString); cipherBean.setNonce(new CounterNonce("vtmw", System.nanoTime())); cipherBean.setKeyAlias("vtcrypt"); cipherBean.setKeyPassword("vtcrypt"); cipherBean.setKeyStore(getTestKeyStore()); cipherBean.setBlockCipherSpec(cipherSpec); final byte[] ciphertext = cipherBean.encrypt(ByteUtil.toBytes(input)); assertEquals(ByteUtil.toString(cipherBean.decrypt(ciphertext)), input); } @Test(dataProvider = "test-streams") public void testEncryptDecryptStream(final String path, final String cipherSpecString) throws Exception { final AEADBlockCipherBean cipherBean = new AEADBlockCipherBean(); final AEADBlockCipherSpec cipherSpec = AEADBlockCipherSpec.parse(cipherSpecString); cipherBean.setNonce(new CounterNonce("vtmw", System.nanoTime())); cipherBean.setKeyAlias("vtcrypt"); cipherBean.setKeyPassword("vtcrypt"); cipherBean.setKeyStore(getTestKeyStore()); cipherBean.setBlockCipherSpec(cipherSpec); final ByteArrayOutputStream tempOut = new ByteArrayOutputStream(8192); cipherBean.encrypt(StreamUtil.makeStream(new File(path)), tempOut); final ByteArrayInputStream tempIn = new ByteArrayInputStream(tempOut.toByteArray()); final ByteArrayOutputStream finalOut = new ByteArrayOutputStream(8192); cipherBean.decrypt(tempIn, finalOut); assertEquals(ByteUtil.toString(finalOut.toByteArray()), ByteUtil.toString(StreamUtil.readAll(path))); } private static KeyStore getTestKeyStore() { final KeyStoreFactoryBean bean = new KeyStoreFactoryBean(); bean.setPassword("vtcrypt"); bean.setResource(new FileResource(new File("src/test/resources/keystores/cipher-bean.jceks"))); bean.setType("JCEKS"); return bean.newInstance(); } private static SecretKey getTestKey() { final KeyStoreBasedKeyFactoryBean<SecretKey> secretKeyFactoryBean = new KeyStoreBasedKeyFactoryBean<>(); secretKeyFactoryBean.setKeyStore(getTestKeyStore()); secretKeyFactoryBean.setPassword("vtcrypt"); secretKeyFactoryBean.setAlias("vtcrypt"); return secretKeyFactoryBean.newInstance(); } }