How to Encrypt / Decrypt with AES in Java 1.8

Here I have created a class that does it in two different ways, the first one is, when you create the key, and the other is when you are given the key, valid key sizes are 128, 192, and 256 for AES algorithm.

There is some steps to follow before executing the code provied, if you don’t probably this class will not work.

1. Download JCE Policy files according to your java version

Since I’m using JDK 1.8 the file I downloaded was jce_policy-8.zip from here.

2. Install JCE Policy files

This simply means that you have to extract the files from the downloaded zip into the following directories %JAVA_HOME%jrelibsecurity and %JAVA_HOME%libsecurity (please note that %JAVA_HOME% is your java installation directory, in my case it is C:\Javajdk1.8.0_121)

3. Run the code below!

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class AESSecretKeyEncryptionDecryptionExample {

    private static final char[] DIGITS_LOWER = {
        '0',
        '1',
        '2',
        '3',
        '4',
        '5',
        '6',
        '7',
        '8',
        '9',
        'a',
        'b',
        'c',
        'd',
        'e',
        'f',
    };
    private static final char[] DIGITS_UPPER = {
        '0',
        '1',
        '2',
        '3',
        '4',
        '5',
        '6',
        '7',
        '8',
        '9',
        'A',
        'B',
        'C',
        'D',
        'E',
        'F',
    };

    private static final String AES_ALGORITHM = "AES";

    public static void main(String args[]) {
        try {
            System.out.println();
            System.out.println(
                "- --- ( AES Message Encryption / Decryption Example ) --- -"
            );
            System.out.println();

            String msg = "Hello World!";

            // Example with 128 bits key
            exampleA(msg, 128);

            System.out.println();

            // Example with 192 bits key
            exampleA(msg, 192);

            System.out.println();

            // Example with 256 bits key
            exampleA(msg, 256);

            System.out.println();
            System.out.println("-----------------------------");
            System.out.println();

            // Example: How to encrypt / decrypt given the secret key in Hex and the message
            exampleB(msg, "BE75B31429EC4139A4C20CCBCB809991"); // 128 bits key

            System.out.println();

            exampleB(msg, "AC2E8746B035517BAFF6EDD103465D26234661DF3F0ADEB7"); // 192 bits key

            System.out.println();

            exampleB(
                msg,
                "6D669C6EC30FB2E5BB9D41A966837F4328ED49ECDE4ECAA42D5D97DF614CC3C0"
            ); // 256 bits key

            System.out.println();
            System.out.println("--- End ---");
        } catch (
            InvalidKeyException
            | NoSuchAlgorithmException
            | NoSuchPaddingException
            | IllegalBlockSizeException
            | BadPaddingException
            | NoSuchProviderException e
        ) {
            System.out.println(e);
            System.out.println(e.getStackTrace());
            System.out.println(e.getCause());

            e.printStackTrace();
        }
    }

    private static void exampleA(String msg, int keySize)
        throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
        SecretKey sk = generateSecretKey(AES_ALGORITHM, keySize);
        System.out.println(
            "Secret Key [" +
            keySize +
            "]: " +
            byteArraytoHexString(sk.getEncoded(), false)
        );

        System.out.println("Message: " + msg);

        byte[] encMsg = encrypt(msg, sk);
        System.out.println(
            "Encrypted Message: " + byteArraytoHexString(encMsg, false)
        );

        String decMsg = decrypt(encMsg, sk);
        System.out.println("Decrypted Message: " + decMsg);

        if (msg.equals(decMsg)) {
            System.out.println("Message encrypted/decrypted correctly!");
        } else {
            System.out.println("Encryption/Decryption FAILURE!");
        }
    }

    private static void exampleB(String msg, String secretKeyHexStr)
        throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
        byte[] secretKeyBytes = hexStringToByteArray(secretKeyHexStr);

        SecretKey secKey = new SecretKeySpec(secretKeyBytes, AES_ALGORITHM);
        int keySize = secretKeyBytes.length * 8;

        System.out.println("Secret Key [" + keySize + "]: " + secretKeyHexStr);
        System.out.println("Message: " + msg);

        String encMsgStr = byteArraytoHexString(encrypt(msg, secKey), false);
        System.out.println("Encrypted Message: " + encMsgStr);

        byte[] encMsg = hexStringToByteArray(encMsgStr);
        String decMsg = decrypt(encMsg, secKey);
        System.out.println("Decrypted Message: " + decMsg);

        if (msg.equals(decMsg)) {
            System.out.println("Message encrypted/decrypted correctly!");
        } else {
            System.out.println("Encryption/Decryption FAILURE!");
        }
    }

    private static byte[] encrypt(String text, SecretKey key)
        throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        byte[] cipheredText = null;

        Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        cipheredText = cipher.doFinal(text.getBytes());

        return cipheredText;
    }

    private static String decrypt(byte[] cipheredText, SecretKey key)
        throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
        byte[] text = null;

        Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        text = cipher.doFinal(cipheredText);

        return new String(text);
    }

    private static SecretKey generateSecretKey(String algorithm, int keySize)
        throws NoSuchAlgorithmException, NoSuchProviderException {
        // keysize: must be equal to 128, 192 or 256
        KeyGenerator kg = KeyGenerator.getInstance(algorithm);
        kg.init(keySize, getSecureRandom());
        return kg.generateKey();
    }

    private static SecureRandom getSecureRandom()
        throws NoSuchAlgorithmException {
        return SecureRandom.getInstance("SHA1PRNG");
    }

    private static String byteArraytoHexString(
        final byte[] data,
        final boolean toLowerCase
    ) {
        return new String(
            encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER)
        );
    }

    private static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] =
                (byte) (
                    (Character.digit(s.charAt(i), 16) << 4) +
                    Character.digit(s.charAt(i + 1), 16)
                );
        }
        return data;
    }

    private static char[] encodeHex(final byte[] data, final char[] toDigits) {
        final int l = data.length;
        final char[] out = new char[l << 1];

        // Two chars form the hex value
        for (int i = 0, j = 0; i < l; i++) {
            out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
            out[j++] = toDigits[0x0F & data[i]];
        }
        return out;
    }
}

The console output should be similar to this:

- --- ( AES Message Encryption / Decryption Example ) --- -

Secret Key [128]: 116B0257139938ECA8B8D5EC6BA93684
Message: Hello World!
Encrypted Message: 8C7C66E4C35E95A17E46855C734E8492
Decrypted Message: Hello World!
Message encrypted/decrypted correctly!

Secret Key [192]: 410C234A18FC6A9A7F633B94D070EB02E7E818859A83D658
Message: Hello World!
Encrypted Message: 117017796D0F698221344E7B7837841D
Decrypted Message: Hello World!
Message encrypted/decrypted correctly!

Secret Key [256]: 77330F70F976C0A6BFADB8C34AF0812F467950544E70D8DE58A311A77CA1980D
Message: Hello World!
Encrypted Message: 341A2ED6ECB3F83E2B97A20A01B93D71
Decrypted Message: Hello World!
Message encrypted/decrypted correctly!

-----------------------------

Secret Key [128]: BE75B31429EC4139A4C20CCBCB809991
Message: Hello World!
Encrypted Message: 00DF615AB02A629E5FAD1AAFC5E0F596
Decrypted Message: Hello World!
Message encrypted/decrypted correctly!

Secret Key [192]: AC2E8746B035517BAFF6EDD103465D26234661DF3F0ADEB7
Message: Hello World!
Encrypted Message: A46B7EF8240DA841E35A237993DAD53F
Decrypted Message: Hello World!
Message encrypted/decrypted correctly!

Secret Key [256]: 6D669C6EC30FB2E5BB9D41A966837F4328ED49ECDE4ECAA42D5D97DF614CC3C0
Message: Hello World!
Encrypted Message: C0D38C93AEE8B341C2BF74640DA74BCC
Decrypted Message: Hello World!
Message encrypted/decrypted correctly!

--- End ---

Sources: