I am a total cryptography novice and was looking to have a simple (ha!) AESEncryption
utility class that I could use for reading/writing files and string with AES keys. Something like:
String toEcnrypt = "This is a secret message!";
AESEcnryption aes = new AESEncryption(); // 256-bit by default
String encrypted = aes.encrypt(toEncrypt);
// Do some stuff
String shouldBeSameAsFirstString = aes.decrypt(encrypted);
The idea being that every time an AESEncryption
is instantiated, a KeySpec
is generated (and can be returned by the API for subsequent storage). Here's what I cooked up after examining the code of much, much brighter people than myself (so if you see your code here, thanks!):
public class AESEncryption {
private SecretKeySpec keySpec;
public AESEncryption()
{
super();
setKeySpec(AES256Encryption.generateAES256KeySpec());
}
// Uses 256-bit encryption by default.
public static SecretKeySpec generateAES256KeySpec()
{
// Stack variables
byte[] byteArray = new byte[16];
SecretKey oTmpKey = null;
KeyGenerator oKeyGen;
try
{
oKeyGen = KeyGenerator.getInstance("AES");
oKeyGen.init(256);
oTmpKey = oKeyGen.generateKey();
}
catch(Throwable oThrown)
{
throw new RuntimeException(oThrown);
}
byteArray = oTmpKey.getEncoded();
return new SecretKeySpec(byteArray, "AES");
}
public String encrypt(final String p_strPlaintext)
{
String strEncrypted = null;
try
{
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
strEncrypted = Base64.encodeBase64String(cipher
.doFinal(p_strPlaintext.getBytes()));
}
catch(Throwable oThrown)
{
System.out.println(oThrown.getMessage());
throw new RuntimeException(oThrown);
}
return strEncrypted;
}
}
For the Base64 En/Decoding I'm using Commons Codec - why? Because like I said I'm a crypto novice and that's the only thing I could find that seemed to get the job done!
When I use this code:
// This creates a unique key spec for this instance.
AESEncryption aes = new AESEncryption();
String toEncrypt = "blah";
// Throws a Throwable and prints the following to the console:
// "Illegal key size or default parameters"
String encrypted = aes.encrypt(toEncrypt);
I saw this question on SO where the asker had the same problem and I see that I may be missing the JCE. Knowing next to nothing about JCE, here's what I've collected:
- The JCE is required for the AES algorithm to execute on the Java platform
- The JCE downloads as a ZIP but really just contains two JARs
I put these 2 JARs (US_export_policy
and local_policy
) on my project's build path (Eclipse) and reran the code. Again the same problem. I know the linked article references installation instructions that recommended including these JARs in the JRE, but at runtime my app should only care about finding the JARs on the classpath - it shouldn't care about where it finds them on the classpath!
Is there anything I can do from inside Elcipse to make sure the JCE is available to my runtime classpath? Or am I way off base and have a bug in my code that is causing these errors?