/* 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.math.BigInteger; import java.security.KeyStore; import org.cryptacular.FailListener; import org.cryptacular.generator.Nonce; import org.cryptacular.generator.sp80038a.BigIntegerCounterNonce; import org.cryptacular.generator.sp80038a.LongCounterNonce; import org.cryptacular.generator.sp80038a.RBGNonce; import org.cryptacular.io.FileResource; import org.cryptacular.spec.BufferedBlockCipherSpec; 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 BufferedBlockCipherBean}. * * @author Middleware Services */ @Listeners(FailListener.class) public class BufferedBlockCipherBeanTest { @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/CBC/PKCS5", new RBGNonce(16), }, // Plaintext is multiple of block size new Object[] { "Four score and seven years ago, our forefathers ", "Blowfish/CBC/None", new RBGNonce(8), }, // OFB new Object[] { "Have you passed through this night?", "Blowfish/OFB/PKCS5Padding", new LongCounterNonce(), }, // CFB new Object[] { "I went to the woods because I wished to live deliberately, to front only the essential facts of life", "AES/CFB/PKCS5Padding", new RBGNonce(16), }, }; } @DataProvider(name = "test-streams") public Object[][] getTestStreams() { return new Object[][] { new Object[] { "src/test/resources/plaintexts/lorem-5000.txt", "AES/CBC/PKCS7", new RBGNonce(16), }, new Object[] { "src/test/resources/plaintexts/lorem-1200.txt", "Twofish/OFB/NULL", new BigIntegerCounterNonce(BigInteger.ONE, 16), }, new Object[] { "src/test/resources/plaintexts/lorem-1200.txt", "AES/CFB/PKCS5", new RBGNonce(16), }, new Object[] { "src/test/resources/plaintexts/lorem-1200.txt", "AES/ECB/PKCS5", new RBGNonce(16), }, }; } @Test(dataProvider = "test-arrays") public void testEncryptDecryptArray(final String input, final String cipherSpecString, final Nonce nonce) throws Exception { final BufferedBlockCipherBean cipherBean = new BufferedBlockCipherBean(); final BufferedBlockCipherSpec cipherSpec = BufferedBlockCipherSpec.parse(cipherSpecString); cipherBean.setNonce(nonce); 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, final Nonce nonce) throws Exception { final BufferedBlockCipherBean cipherBean = new BufferedBlockCipherBean(); final BufferedBlockCipherSpec cipherSpec = BufferedBlockCipherSpec.parse(cipherSpecString); cipherBean.setNonce(nonce); 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(); } }