I've implemented AES encryption with certain task-specific parameters using standard Java tools and BouncyCastle provider for specific AES algorithm.
Here is the code:
private byte[] aesEncryptedInfo(String info) throws UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidParameterSpecException, InvalidAlgorithmParameterException, NoSuchProviderException {
Security.addProvider(new BouncyCastleProvider());
SecretKey secret = new SecretKeySpec(CUSTOMLONGSECRETKEY.substring(0, 32).getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(VECTOR_SECRET_KEY.getBytes()));
return cipher.doFinal(info.getBytes("UTF-8"));
}
In some environments this code requires special policy files. See related question: InvalidKeyException Illegal key size
My goal is to reimplement it using third-party library, ideally I would use bouncy castle which is already used as provider. The library should have no restictions of standard java policy files. In other words there should be no restrictions.
Please suggest in your answers how to reimplement it using BouncyCastle or other third-party library which can work without restrictions mentioned. Ideally I would see the code :-)
Thank you very much for reading!
After a delay I now happy to post a solution. Hope that someone can benefit from it because Bouncy Castle documentation is not filled with a lot of examples :-)
private byte[] aesEncryptedInfo(String info)
// Creating AES/CBC/PKCS7Padding cipher with specified Secret Key and Initial Vector
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()), new PKCS7Padding());
cipher.init(true, new ParametersWithIV(new KeyParameter(CUSTOMLONGSECRETKEY.getBytes()), VECTOR_SECRET_KEY.getBytes()));
byte[] inputData = info.getBytes("UTF-8");
int outBlockSize = cipher.getOutputSize(inputData.length);
byte[] outputData = new byte[outBlockSize];
int outLength = cipher.processBytes(inputData, 0, inputData.length, outputData, 0);
outLength += cipher.doFinal(outputData, outLength);
if (outLength != outBlockSize) {
return Arrays.copyOf(outputData, outLength);
}
else {
return outputData;
}
}
By the way I found two differences between Java API and Bouncy Castle API: 1. Bouncy Castle uses composition of objects to create needed cipher. While Java API uses string to identify needed cipher. 2. BC encryption code slightly bigger, while Java API code is more compact.
The solution is full replacement for original Java API implementation - the proof is a custom unit test that I made.