• Java
    • JAXB Tutorial
      • What is JAXB
      • JAXB Marshalling Example
      • JAXB UnMarshalling Example
  • Spring Tutorial
    • Spring Core Tutorial
    • Spring MVC Tutorial
      • Quick Start
        • Flow Diagram
        • Hello World Example
        • Form Handling Example
      • Handler Mapping
        • BeanNameUrlHandlerMapping
        • ControllerClassNameHandlerMapping
        • SimpleUrlHandlerMapping
      • Validation & Exception Handling
        • Validation+Annotations
        • Validation+ResourceBundle
        • @ExceptionHandler
        • @ControllerAdvice
        • Custom Exception Handling
      • Form Tag Library
        • Textbox Example
        • TextArea Example
        • Password Example
        • Dropdown Box Example
        • Checkboxes Example
        • Radiobuttons Example
        • HiddenValue Example
      • Misc
        • Change Config file name
    • Spring Boot Tutorial
  • Hibernate Tutorial
  • REST Tutorial
    • JAX-RS REST @PathParam Example
    • JAX-RS REST @QueryParam Example
    • JAX-RS REST @DefaultValue Example
    • JAX-RS REST @Context Example
    • JAX-RS REST @MatrixParam Example
    • JAX-RS REST @FormParam Example
    • JAX-RS REST @Produces Example
    • JAX-RS REST @Consumes Example
    • JAX-RS REST @Produces both XML and JSON Example
    • JAX-RS REST @Consumes both XML and JSON Example
  • Miscellaneous
    • JSON Parser
      • Read a JSON file
      • Write JSON object to File
      • Read / Write JSON using GSON
      • Java Object to JSON using JAXB
    • CSV Parser
      • Read / Write CSV file
      • Read/Parse/Write CSV File – OpenCSV
      • Export data into a CSV File
      • CsvToBean and BeanToCsv – OpenCSV

JavaInterviewPoint

Java Development Tutorials

Java AES 256 GCM Encryption and Decryption Example | JCE Unlimited Strength

June 4, 2019 by javainterviewpoint 5 Comments

Advanced Encryption Standard (AES) algorithm in Galois Counter Mode (GCM), known as AES-GCM. Advanced Encryption Standard with Galois Counter Mode (AES-GCM) is introduced by the National Institute for Standard and Technology (NIST). In this article, we will learn about  Java AES 256 GCM Encryption and Decryption

AES-GCM is a block cipher mode of operation that provides high speed of authenticated encryption and data integrity. In GCM mode, the block encryption is transformed into stream encryption, and therefore no padding is needed. The Additional Authenticated Data (AAD) will not be encrypted but used in the computation of Authentication Tag. The authenticated encryption operation takes Initialization Vector (IV), Additional Authenticated Data (AAD), Secret Key and 128-bit plaintext and gives a 128-bit ciphertext and authentication tag

Before getting into the implementation of AES GCM encryption algorithm, let’s first understand the basic difference between AES CBC and AES GCM.

Difference between AES-CBC and AES-GCM?

Both GCM and CBC Modes involves a block cipher and an exclusive-or (XOR) but internally they both work in a different manner. Let’s understand the difference between them.

In CBC mode, you encrypt a block of data by taking the current plaintext block and XOR’ing with the previous ciphertext block and which cannot be written in parallel, this significantly affects the performance of AES-CBC encryption and AES-CBC also is vulnerable to padding oracle attacks.

GCM mode maintains a counter for each block of data and sends the current value of the counter to the block cipher and the output of the block cipher is XOR’ed with the plain text to get the ciphertext. The counter mode of operation is designed to turn block ciphers into stream ciphers. AES GCM is written in parallel and each block with AES GCM can be encrypted independently, hence the performance is significantly higher than AES CBC.

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy

Without JCE policy files and when we try to generate a 256-bit key for AES 256 GCM encryption,  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”

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

  1. JCE for different versions of Java can be downloaded from the Oracle download page.
  2. 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
  3. Unzip the downloaded policy zip file.
  4. 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 GCM Encryption and Decryption Example

Java AES 256 GCM Encryption and Decryption Example

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.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AES_GCM_Example
{
    static String plainText = "This is a plain text which need to be encrypted by Java AES 256 GCM Encryption Algorithm";
    public static final int AES_KEY_SIZE = 256;
    public static final int GCM_IV_LENGTH = 12;
    public static final int GCM_TAG_LENGTH = 16;

    public static void main(String[] args) throws Exception
    {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(AES_KEY_SIZE);
       
        // Generate Key
        SecretKey key = keyGenerator.generateKey();
        byte[] IV = new byte[GCM_IV_LENGTH];
        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/GCM/NoPadding");
        
        // Create SecretKeySpec
        SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");
        
        // Create GCMParameterSpec
        GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);
        
        // Initialize Cipher for ENCRYPT_MODE
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);
        
        // 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/GCM/NoPadding");
        
        // Create SecretKeySpec
        SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");
        
        // Create GCMParameterSpec
        GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);
        
        // Initialize Cipher for DECRYPT_MODE
        cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
        
        // Perform Decryption
        byte[] decryptedText = cipher.doFinal(cipherText);
        
        return new String(decryptedText);
    }
}
  • The KeyGenerator Class is used to generate symmetric encryption keys, the getInstance() method returns the KeyGenerator instance for the algorithm which is passed as a parameter, in our case it is AES
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
  • Now we need to generate a 256-bit key for AES 256 GCM (Note: Installing Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy is a must). Call the init() method on top of the KeyGenerator instance which we have created in the previous step, we need to pass the bit size of the keys to generate.
keyGenerator.init(AES_KEY_SIZE);
  • 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. SecureRandom class provides a cryptographically strong random number generator
byte[] IV = new byte[GCM_IV_LENGTH];
SecureRandom random = new SecureRandom();
random.nextBytes(IV);
  • The encryption and decryption are handled by the Cipher class. Cipher class instance is created by calling the getInstance() method passing the Cipher name as the parameter, in our case, it is AES/GCM/NoPadding
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
  • Cipher name is made up 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 – GCM
    • The third part is the padding scheme which is going to be used – NoPadding. Since GCM Mode transforms block encryption into stream encryption
  • SecretKeySpec is a subclass of SecretKey, SecretKeySpec is a concrete class that allows for easy construction of SecretKey from an existing key. 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");
  • When using other block cipher modes such as CBC mode, we require only the Initialization Vector (IV), whereas in the case of GCM mode we required Initialization Vector (IV) and Authentication Tag and hence we need to use GCMParameterSpec instead of IvParameterSpec
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);
  • Once the Cipher instance is created we need to initialize the cipher instance for encryption or decryption by calling the init() method
    • Cipher Mode – Cipher.ENCRYPT_MODE (or) Cipher.DECRYPT_MODE
    • SecretKeySpec
    • GCMParameterSpec
cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);

(or)

cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
  • 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:

Other interesting articles which you may like …

  • JavaScript HMAC SHA256 Hash Example
  • JavaScript SHA256 Hash Example
  • ChaCha20 Poly1305 Encryption and Decryption
  • ChaCha20 Encryption and Decryption
  • RSA Encryption and Decryption
  • AES 256 Encryption and Decryption
  • AES 128 Encryption and Decryption
  • Java URL Encode and Decode Example
  • Java Salted Password Hashing
  • Google Tink Example – Google Cryptography
  • Constructor in Java
  • Private Constructors in Java
  • Java Constructor Chaining with example
  • Java – Constructor in an Interface?
  • Constructor.newInstance() method
  • Parameterized Constructor in Java
  • Java 8 – Lambda Expressions
  • Java 8 – ForEach Example
  • Java 8 Default Methods in Interface
  • Multiple Inheritance in Java 8 through Interface
  • Java 9 – jdeprscan
  • Private Methods in Interfaces Java 9
  • Java Method Overloading Example
  • Java Constructor Overloading Example
  • Java this keyword | Core Java Tutorial
  • Java super keyword
  • Abstract Class in Java
  • Interface in Java and Uses of Interface in Java
  • What is Marker Interface
  • Serialization and Deserialization in Java with Example
  • Generate SerialVersionUID in Java
  • Java Autoboxing and Unboxing Examples
  • Use of Java Transient Keyword – Serialization Example
  • Use of static Keyword in Java
  • What is Method Overriding in Java
  • Encapsulation in Java with Example
  • Final Keyword in Java | Java Tutorial
  • Java Static Import
  • Java – How System.out.println() really work?
  • Java Ternary operator
  • Java newInstance() method

Filed Under: Core Java, Java Tagged With: AES 256, AES 256 GCM, AES GCM, Java AES 256 GCM, Java AES 256 GCM Encryption

Comments

  1. Thaara says

    June 19, 2019 at 8:06 pm

    Great article!
    Quick question though:
    Just dropping the JARS under $JAVA_HOME/jre/lib/security didn’t work for me. I also noticed that those two JARS aren’t present directly under $JAVA_HOME/jre/lib/security. They are present in $JAVA_HOME/jre/lib/security/policy/unlimited and $JAVA_HOME/jre/lib/security/policy/limited directories.

    I copied those JARS into both the directories. It still doesn’t work. Am I missing something?

    Reply
    • javainterviewpoint says

      June 19, 2019 at 10:03 pm

      What is the version of Java which you are using?

      Reply
      • javainterviewpoint says

        June 19, 2019 at 10:15 pm

        Gotcha, This behavior is introduced in JDK 8 ver 151.
        You got two ways to enable unlimited strength
        1. Locate the file java.security under /lib/security/java.security and search for the line #crypto.policy=unlimited. Now just remove # to uncomment and enable JCE Unlimited Strength
        2. Alternatively, you can add the below line in the main method [Add it as a first line in main() method]
        Security.setProperty(“crypto.policy”, “unlimited”);

        Reply
  2. Chigozie says

    July 9, 2019 at 7:37 pm

    If I wanted to use AES 128 GCM with this implementation is it as simple as changing the key length variable to 128? The IVs should always be the same since its GCM. Is there anything else I would need to change

    Reply
    • javainterviewpoint says

      July 9, 2019 at 9:51 pm

      All you need to do is change key length from 256 to 128, remaining things can remain the same.

      Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Java Basics

  • JVM Architecture
  • Object in Java
  • Class in Java
  • How to Set Classpath for Java in Windows
  • Components of JDK
  • Decompiling a class file
  • Use of Class.forName in java
  • Use Class.forName in SQL JDBC

Oops Concepts

  • Inheritance in Java
  • Types of Inheritance in Java
  • Single Inheritance in Java
  • Multiple Inheritance in Java
  • Multilevel Inheritance in Java
  • Hierarchical Inheritance in Java
  • Hybrid Inheritance in Java
  • Polymorphism in Java – Method Overloading and Overriding
  • Types of Polymorphism in java
  • Method Overriding in Java
  • Can we Overload static methods in Java
  • Can we Override static methods in Java
  • Java Constructor Overloading
  • Java Method Overloading Example
  • Encapsulation in Java with Example
  • Constructor in Java
  • Constructor in an Interface?
  • Parameterized Constructor in Java
  • Constructor Chaining with example
  • What is the use of a Private Constructors in Java
  • Interface in Java
  • What is Marker Interface
  • Abstract Class in Java

Java Keywords

  • Java this keyword
  • Java super keyword
  • Final Keyword in Java
  • static Keyword in Java
  • Static Import
  • Transient Keyword

Miscellaneous

  • newInstance() method
  • How does Hashmap works internally in Java
  • Java Ternary operator
  • How System.out.println() really work?
  • Autoboxing and Unboxing Examples
  • Serialization and Deserialization in Java with Example
  • Generate SerialVersionUID in Java
  • How to make a class Immutable in Java
  • Differences betwen HashMap and Hashtable
  • Difference between Enumeration and Iterator ?
  • Difference between fail-fast and fail-safe Iterator
  • Difference Between Interface and Abstract Class in Java
  • Difference between equals() and ==
  • Sort Objects in a ArrayList using Java Comparable Interface
  • Sort Objects in a ArrayList using Java Comparator

Follow

  • Coding Utils

Useful Links

  • Spring 4.1.x Documentation
  • Spring 3.2.x Documentation
  • Spring 2.5.x Documentation
  • Java 6 API
  • Java 7 API
  • Java 8 API
  • Java EE 5 Tutorial
  • Java EE 6 Tutorial
  • Java EE 7 Tutorial
  • Maven Repository
  • Hibernate ORM

About JavaInterviewPoint

javainterviewpoint.com is a tech blog dedicated to all Java/J2EE developers and Web Developers. We publish useful tutorials on Java, J2EE and all latest frameworks.

All examples and tutorials posted here are very well tested in our development environment.

Connect with us on Facebook | Privacy Policy | Sitemap

Copyright ©2023 · Java Interview Point - All Rights Are Reserved ·