package com.ambientideas.cryptography; import java.security.SecureRandom; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import junit.framework.Assert; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.Test; /** * Use the standard JCE classes for crypto but with the BouncyCastle * provider providing the AES algorithm with CTR (counter) mode and no padding. */ public class TestExampleBCPBEViaJCE { private static final String salt = "Use this phrase as the input to salt the encryption (should be random)"; private static final int iterations = 2000; private static final int keyLength = 256; private static final SecureRandom random = new SecureRandom(); static final String PASSPHRASE = "MySup3rSecRe7Pa$$"; static final String PLAINTEXT = "Four score and seven years ago."; @Test public void test() throws Exception { Security.insertProviderAt(new BouncyCastleProvider(), 1); byte [] ciphertext = encrypt(PASSPHRASE, PLAINTEXT); String decryptedPlaintext = decrypt(PASSPHRASE, ciphertext); System.out.println("Decrypted plaintext: " + decryptedPlaintext); Assert.assertEquals(PLAINTEXT, decryptedPlaintext); } private static byte [] encrypt(String passphrase, String plaintext) throws Exception { SecretKey key = generateKey(passphrase); Cipher cipher = Cipher.getInstance("AES/CTR/NOPADDING"); cipher.init(Cipher.ENCRYPT_MODE, key, generateIV(cipher), random); return cipher.doFinal(plaintext.getBytes()); } private static String decrypt(String passphrase, byte [] ciphertext) throws Exception { SecretKey key = generateKey(passphrase); Cipher cipher = Cipher.getInstance("AES/CTR/NOPADDING"); cipher.init(Cipher.DECRYPT_MODE, key, generateIV(cipher), random); return new String(cipher.doFinal(ciphertext)); } private static SecretKey generateKey(String passphrase) throws Exception { PBEKeySpec keySpec = new PBEKeySpec(passphrase.toCharArray(), salt.getBytes(), iterations, keyLength); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC"); return keyFactory.generateSecret(keySpec); } private static IvParameterSpec generateIV(Cipher cipher) throws Exception { byte [] ivBytes = new byte[cipher.getBlockSize()]; random.nextBytes(ivBytes); return new IvParameterSpec(ivBytes); } }