AES (Advanced Encryption Standard) is a strong symmetric encryption algorithm. AES supports key lengths of 128, 192 and 256 bit.In this article, we will learn AES 256 Encryption and Decryption.
AES uses the same secret key is used for the both encryption and decryption. Unlike AES 128 bit encryption and decryption, if we need a stronger AES 256 bit key, we need to have Java cryptography extension (JCE) unlimited strength jurisdiction policy files.
If we have not installed the JCE we will be getting the error like “java.security.InvalidKeyException: Illegal key size” or “org.apache.xml.security.encryption.XMLEncryptionException: Illegal key size or default parameters”
Exception in thread "main" java.security.InvalidKeyException: Illegal key size at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1034) at javax.crypto.Cipher.implInit(Cipher.java:800) at javax.crypto.Cipher.chooseProvider(Cipher.java:859) at javax.crypto.Cipher.init(Cipher.java:1370) at javax.crypto.Cipher.init(Cipher.java:1301) at com.javainterviewpoint.AES_Encryption.encrypt(AES_Encryption.java:51) at com.javainterviewpoint.AES_Encryption.main(AES_Encryption.java:31)
(or)
Caused by: org.apache.xml.security.encryption.XMLEncryptionException: Illegal key size or default parameters Original Exception was java.security.InvalidKeyException: Illegal key size or default parameters at org.apache.xml.security.encryption.XMLCipher.encryptData(Unknown Source) at org.apache.xml.security.encryption.XMLCipher.encryptData(Unknown Source) at org.apache.xml.security.encryption.XMLCipher.encryptElement(Unknown Source) at org.apache.xml.security.encryption.XMLCipher.doFinal(Unknown Source) at org.apache.ws.security.message.WSSecEncrypt.doEncryption(WSSecEncrypt.java:593) ... 24 more
Installing Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files
We need to manually download the JCE Policy files for Java 6, Java 7 and Java 8.
Java 6, Java 7 & Java 8
- JCE for different versions of Java can be downloaded from the Oracle download page.
- Download the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy File for the JVM which you have installed.
- jce_policy-6.zip for Java 6
- UnlimitedJCEPolicyJDK7.zip for Java 7
- jce_policy-8.zip for Java 8
- Unzip the downloaded policy zip file.
- Copy local_policy.jar and US_export_policy.jar to the $JAVA_HOME/jre/lib/security, these jars will be already present and we need to overwrite them.
From Java 9 onwards default JCE policy files bundled in this Java Runtime Environment allow for “unlimited” cryptographic strengths.
Java AES 256 Encryption and Decryption
package com.javainterviewpoint; import java.security.SecureRandom; import java.util.Base64; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class AES_Encryption { static String plainText = "This is a plain text which need to be encrypted by Java AES 256 Algorithm in CBC Mode"; public static void main(String[] args) throws Exception { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(256); // Generate Key SecretKey key = keyGenerator.generateKey(); // Generating IV. byte[] IV = new byte[16]; SecureRandom random = new SecureRandom(); random.nextBytes(IV); System.out.println("Original Text : "+plainText); byte[] cipherText = encrypt(plainText.getBytes(),key, IV); System.out.println("Encrypted Text : "+Base64.getEncoder().encodeToString(cipherText)); String decryptedText = decrypt(cipherText,key, IV); System.out.println("DeCrypted Text : "+decryptedText); } public static byte[] encrypt (byte[] plaintext,SecretKey key,byte[] IV ) throws Exception { //Get Cipher Instance Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //Create SecretKeySpec SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES"); //Create IvParameterSpec IvParameterSpec ivSpec = new IvParameterSpec(IV); //Initialize Cipher for ENCRYPT_MODE cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); //Perform Encryption byte[] cipherText = cipher.doFinal(plaintext); return cipherText; } public static String decrypt (byte[] cipherText, SecretKey key,byte[] IV) throws Exception { //Get Cipher Instance Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //Create SecretKeySpec SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES"); //Create IvParameterSpec IvParameterSpec ivSpec = new IvParameterSpec(IV); //Initialize Cipher for DECRYPT_MODE cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); //Perform Decryption byte[] decryptedText = cipher.doFinal(cipherText); return new String(decryptedText); } }
- KeyGenerator Class is used to generate symmetric encryption keys, we will get the KeyGenerator instance by calling the getInstance() method passing the name of the algorithm as a parameter, in our case it is AES
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
- Once the KeyGenerator instance is created, we need to initialize it by calling its init() method, we need to pass the bit size of the keys to generate. We passed 256 since we are generating 256 bit key.
keyGenerator.init(256);
- Once the KeyGenerator is initialized, we can generate the symmetric SecretKey by calling the generateKey() method on top of the KeyGenerator instance.
SecretKey key = keyGenerator.generateKey();
- The IV stands for Initialization Vector, it is an arbitrary number which will be used along with SecretKey during encryption. The IV adds randomness to the start of the encryption process, it is also called as nonce as it will be used only once.
byte[] IV = new byte[16]; SecureRandom random = new SecureRandom(); random.nextBytes(IV);
- Cipher class is the one that handles the actual encryption and decryption. Cipher class instance is created by calling the getInstance() method passing the Cipher name as the parameter, in our case it is AES/CBC/PKCS5Padding
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- Cipher name is composed of 3 parts
- The first part is the name of the algorithm – AES
- The second part is the mode in which the algorithm should be used – CBC
- The third part is the padding scheme which is going to be used – PKCS5Padding
- The SecretKeySpec provides the mechanism of converting byte data into a secret key suitable to be passed to init() method of the Cipher class.
SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");
- IvParameterSpec is a wrapper for an initialization vector, IV gets its randomness from the way IvParameterSpec is configured.
IvParameterSpec ivSpec = new IvParameterSpec(IV);
- Once the Cipher instance is created we need to initilazie the cipher instance by calling the init() method. We need to pass the 3 parameters to the init() method.
- Cipher Mode – Cipher.ENCRYPT_MODE (or) Cipher.DECRYPT_MODE
- SecretKeySpec
- IvParameterSpec
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
- In order to encrypt we will be calling the doFinal() method on top of the Cipher instance passing the plainText as the parameter
byte[] cipherText = cipher.doFinal(plaintext);
- We will be encoding the ciperText with Base64 to ensure it to be intact without modification when it is transferred.
Base64.getEncoder().encodeToString(cipherText)
- To decrypt we need to pass the cipherText to the doFinal() method of the Cipher instance
byte[] decryptedText = cipher.doFinal(cipherText);
Output:
Original Text : This is a plain text which need to be encrypted by Java AES 256 Algorithm in CBC Mode Encrypted Text : FXTy0XUrT4ZRthTdzyDBjA/M25r9J4rkBaRaEHz2KEYi4PGB9GiNW63NUBTBvdC6suX6BpBHfMDL1xYJFQcp6iOX1CV2FpGYRklCDaABEyxlqDeX58aa9XpBXYL7ouEi DeCrypted Text : This is a plain text which need to be encrypted by Java AES 256 Algorithm in CBC Mode
Leave a Reply