Implement AES-256 encryption/decryption using Java

Tutorial #76: Implement AES-256 encryption/decryption using Java

The Advanced Encryption Standard (AES) is an encryption algorithm designed for securing electronic data established by the U.S National Institute of Standards and Technology (NIST) in 2001. AES is based on Rijndael cipher developed by cryptographers Joan Daemen and Vincent Rijmen. AES carries out its operation on a 4×4 column major order matrix of bytes. The key size used for an AES cipher specifies the number of repetitions of transformation rounds that convert the input, called the plaintext, into the final output, called the ciphertext.
AES is currently available in three key sizes: 128, 192 and 256 bits.The design and strength of all key lengths of the AES algorithm are sufficient to protect classified information up to the SECRET level. As far as security is concerned, AES is considered to be more secure than its predecessor DES. For more information please refer this link.
In this tutorial, we will learn how to implement AES-256 encryption using Java. We will use the Java Cryptography Extension for encryption, decryption, key generation etc. Before proceeding make sure you have downloaded the jurisdiction policy for your respective Java platform from over here. Place the policy files in the {JDK_HOME}\jre\lib\security folder.
Pre-requisites: Eclipse IDE, JDK 1.6 or above
Step 1: Create Java project
Open Eclipse IDE and create a new Java console application project calledTestAESExample.
Step 2: Create Java class
Create a new Java class called AESDemo with package name com.example and add the following code!
AESDemo.java
import java.security.AlgorithmParameters;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
 
public class AESDemo {
 
    private static final String password = "test";
    private static String salt;
    private static int pswdIterations = 65536  ;
    private static int keySize = 256;
    private byte[] ivBytes;
 
    public String encrypt(String plainText) throws Exception {  
         
        //get salt
        salt = generateSalt();     
        byte[] saltBytes = salt.getBytes("UTF-8");
         
        // Derive the key
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        PBEKeySpec spec = new PBEKeySpec(
                password.toCharArray(),
                saltBytes,
                pswdIterations,
                keySize
                );
 
        SecretKey secretKey = factory.generateSecret(spec);
        SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
 
        //encrypt the message
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secret);
        AlgorithmParameters params = cipher.getParameters();
        ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();
        byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
        return new Base64().encodeAsString(encryptedTextBytes);
    }
 
    @SuppressWarnings("static-access")
    public String decrypt(String encryptedText) throws Exception {
 
        byte[] saltBytes = salt.getBytes("UTF-8");
        byte[] encryptedTextBytes = new Base64().decodeBase64(encryptedText);
 
        // Derive the key
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        PBEKeySpec spec = new PBEKeySpec(
                password.toCharArray(),
                saltBytes,
                pswdIterations,
                keySize
                );
 
        SecretKey secretKey = factory.generateSecret(spec);
        SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
 
        // Decrypt the message
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes));
     
 
        byte[] decryptedTextBytes = null;
        try {
            decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
 
        return new String(decryptedTextBytes);
    }
 
    public String generateSalt() {
        SecureRandom random = new SecureRandom();
        byte bytes[] = new byte[20];
        random.nextBytes(bytes);
        String s = new String(bytes);
        return s;
    }
}
Note: In the above example, salt is generated randomly by the generateSalt()method. To implement Base64 encoding and decoding, you need to download the commons-codec library from over here.
Finally, lets add our main class Test.java as follows!
Test.java
package com.example;
 
public class Test {
     
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
 
        AESDemo d = new AESDemo();
             
        System.out.println("Encrypted string:" + d.encrypt("Hello"));          
        String encryptedText = d.encrypt("Hello");
        System.out.println("Decrypted string:" + d.decrypt(encryptedText));        
 
    }
}
Save all changes. Make sure no errors are present. Run the application. Depending upon the plainText provided you will get the encrypted data.
output
Karan BalkarAbout Karan Balkar
self proclaimed extraterrestrial fandroid, computer engineer, amateur gamer and die hard punk rock fan!

16 thoughts on “Tutorial #76: Implement AES-256 encryption/decryption using Java

  1. Exception in thread “main” java.security.InvalidKeyException: Illegal key size or default parameters
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1021)
    at javax.crypto.Cipher.implInit(Cipher.java:796)
    at javax.crypto.Cipher.chooseProvider(Cipher.java:859)
    at javax.crypto.Cipher.init(Cipher.java:1229)
    at javax.crypto.Cipher.init(Cipher.java:1166)
    at viz_3_aes_rsa.AESDemo.encrypt(AESDemo.java:41)

Comments

Popular posts from this blog

VMware fix for Invalid manifest and ova file import failed errors

SOAPUI - import certificate

Centrally Managed Users (CMU) - New Feature in Oracle Database 18c