Encryption and decryption are one of the earliest applications of computer systems. As technology has progressed, better encryption standards have been introduced by every well-known language, one of which is Java. To facilitate its developers, Java AES encryption offers several modes of AES for improved data encryption.

What is AES?

AES (Advanced Encryption Standard) also referred by its original name “Rijndael” is a set of specifications required for the encryption of electronic data. It was established by the U.S. National Institute of Standards and Technology (NIST) in 2001. Later, AES became a standard for encryption and is now used worldwide.

Java AES Encryption:

AES is one of the strong symmetric encryption algorithms used in java. It is an iterative, symmetric-key block cipher used for encryption of data. Java AES encryption is implemented with Cryptography Architecture (JCA) within the JDK. It supports cryptographic keys length of 128, 192, and 256 bits for encryption and decryption of data in blocks of 128 bits. If the data to be encrypted does not meet the block size of a minimum 128 bits, it needs to be padded.

Java Developer Jobs

For Java AES Encryption three parameters are required, 

1. Input data:

Java AES Encryption can be used for various types of data including strings, files, objects. It can also be used for password-protected data.

2. The encryption key:

There are two ways for generating an encryption key for the Java AES encryption. It can be done by either generating from a random sequence of numbers or by deriving a key from the password set by the user for data protection.

For generating a random number, there is a class in java called SecureRandomThis class provides a cryptographically strong random number generator (RNG). Now for generating a secret key, we can use another class called KeyGenerator

The code snippet below shows the method definition for generating an AES key with the size 128, 192, and 256 bits,

1.	public static SecretKey generateKey(int n) throws NoSuchAlgorithmException {
2.	    KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
3.	    keyGenerator.init(n);
4.	    SecretKey key = keyGenerator.generateKey();
5.	    return key;
6.	}

The second approach that is to derive the encryption key from a given password. It can be done by using a password-based key derivation function such as PBKDF2. It also requires a salt value and a count number. This approach is further explained later in this article.

3. IV (Initialization Vector):

IV or Initialization Vector is another pseudo-random value used for encryption. It must be of the same size as the data block to be encrypted. The same class, SecureRandom is used for generating a random IV number.

Following method is used for generation of a 16 bit IV:

1.	public static IvParameterSpec generateIv() {
2.	    byte[] iv = new byte[16];
3.	    new SecureRandom().nextBytes(iv);
4.	    return new IvParameterSpec(iv);
5.	} 

AES modes available in Java:

The Java AES encryption is implemented using 6 different modes of encryption. Every mode offers different improvements over the other. Some can be applied to strengthen the encryption while some offer better authentication. Each mode has its strength and weakness. 

Following are the 6 modes of AES encryption that can be implemented in Java,

  1. ECB (Electronic Code Book)
  2. CBC (Cipher Block Chaining)
  3. CFB (Cipher FeedBack)
  4. OFB (Output FeedBack)
  5. CTR (Counter)
  6. GCM (Galois/Counter Mode)

· Electronic Code Book

ECB (Electronic Code Book) is one of the simplest modes of AES Java. The encryption is done by dividing the whole data to be encrypted into multiple blocks of 128 bits. Being part of the same data, each block is encrypted and can be decrypted with the same key.

This is the main weakness of this mode as identical plaintext blocks would be encrypted to identical ciphertext blocks. The only reason this mode is used in Java AES encryption is for data smaller than 128 bits. 

Unfortunately, despite being less secure it is still often used by java developers because this mode does not require an IV that makes it seems to be easier than other Java AES encryption modes.

Java AES encrypt data with a minimum key length of 128 bits. That is where padding comes into play. As the last block of data could be less than 128 bits, the missing bits in the last block is filled up with zeros. There is practically no security implication in using zeros for padding in AES java.

The code below is a java AES encryption example. It performs the java AES encryption using ECB mode,

1.	import java.security.*;
2.	 import javax.crypto.*;
3.	 import javax.crypto.spec.*;
4.	 class AES_ECB
5.	 {
6.	  public KeyGenerator keygenerator;
7.	  public SecretKey myKey;
8.	  Cipher c;
9.	  publisc AES_ECB() throws Exception
10.	   { 
11.	   // Key generation
12.	   keygenerator = KeyGenerator.getInstance("AES");
13.	   myKey = keygenerator.generateKey();
14.	   // Creating the cipher
15.	   c = Cipher.getInstance("AES/ECB/PKCS5Padding"); 
16.	  }
17.	  public byte[] perfromEncryption(String s) throws Exception
18.	  {
19.	      // Initialize the cipher for encryption
20.	      c.init(Cipher.ENCRYPT_MODE, myKey);
21.	      //data to be encrypted
22.	      byte[] text = s.getBytes();
23.	      // Encrypt the data
24.	      byte[] textEncrypted = c.doFinal(text);
25.	    return(textEncrypted);
26.	  }
27.	  public String PerformDecryption(byte[] s)throws Exception
28.	  {
29.	      // Initialize the same cipher for decrypting data
30.	      c.init(Cipher.DECRYPT_MODE, myKey);
31.	      // Decrypt the data
32.	      byte[] textDecrypted = c.doFinal(s);
33.	      return(new String(textDecrypted));
34.	  }
35.	 }
36.	
37.	 public static void main(String[] argv) throws Exception
38.	  {
39.	   AES_ECB obj = new AES_ECB();
40.	   byte[] str=obj.performEncryption("This data in encrypted using Java AES ECB");
41.	   System.out.println("Encrypted String : "+str);
42.	   System.out.println("Decrypted String : " + obj.performDecryption(str));
43.	     
44.	  }
45.	 }

· Cipher Block Chaining

CBC mode (Cipher Block Chaining) is an improvement over the ECB. CBC applies XORs to the current block of plaintext with the previous ciphertext block. This is done so that, each ciphertext block depends on all the plaintext blocks processed before it. 

For the first block, as it does not have any previous ciphertext block, a random initialization vector (IV) of 128 bits is used. By using the zeros for padding, ECB is comparatively less security as every encryption with the same key and plaintext would end up with the same ciphertext. That is why a random block of IV is used in CBC. An IV can be public, as it must be random and only used for once. 

When transmitting the encrypted data, it is a common practice in AES Java code to just add the IV at the start of the actual cipher message. 

Following is a Java AES encryption example code with CBC mode.

1.	private static final String key = "aesEncryptionKey";
2.	private static final String IV = "encryptionIntVec";
3.	 
4.	public static String encryption(String value) {
5.	    try {
6.	        IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));
7.	        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
8.	 
9.	        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
10.	        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
11.	 
12.	        byte[] encrypted = cipher.doFinal(value.getBytes());
13.	        return Base64.encodeBase64String(encrypted);
14.	    } catch (Exception ex) {
15.	        ex.printStackTrace();
16.	    }
17.	    return null;
18.	}

 This code demonstrates the decryption process

1.	public static String decryption(String encrypted) {
2.	    try {
3.	        IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));
4.	        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
5.	 
6.	        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
7.	        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
8.	        byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
9.	        return new String(original);
10.	    } catch (Exception ex) {
11.	        ex.printStackTrace();
12.	    }
13.	    return null;
14.	}

· Counter Mode

Another mode that is used for AES java encryption is CTR or Counter mode. Unlike CBC and EBS it does not require padding because it turns the block cipher into a stream cipher. Initially, all blocks are numbered starting from 0. These numbers are the counter values assigned to every block. Every block is then encrypted with the key, the IV and the counter value.

The main advantage over CBC is that encryption can be done parallelly and each block depends on the IV, not just the first one. Due to parallel encryption, the noise in one block also does not affect other blocks. It is to be noted that an IV must never be reused with the same key as then the key can be easily calculated making it prone to attacks.

· Galois/Counter Mode

GCM (Galois/Counter Mode) is one of the best Java AES encryption modes as it offers authenticated encryption. Along with data encryption, it also assures the confidentiality and authenticity of the data.

GCM can be considered as an improved version of CTR mode. It calculates a 128-bit long authentication tag with encryption of data. The authentication tag is then usually joined with the ciphertext which is later used for the authentication of decrypted data.

Another highlighted feature of GCM is that it can also authenticate additional information that is not encrypted with the plaintext. It is useful because some in certain cases the hackers can change the additional information making the encrypted data useless after encryption or could affect its properties. For instance, the date of creation is associated with the encryption data which is used to check if the data must be re-encrypted or not. If it is altered during an attack, GCM can verify if this piece of information is valid or not. It maintains the integrity of the data after encryption.

· Cipher Feedback and Output Feedback

CFB (Cipher Feedback) and OFB (output feedback) are both very similar modes. They can be used as a stream cipher. First, the IV is encrypted then it XORs the plaintext blocks to get ciphertext. 

The only difference in both of them is that in CFB encryption cannot be parallelized due to which CFB requires padding data whereas OFB does not.

Java AES Password-Based encryption and decryption.

Generating a random key is relatively easier but for password-based encryption, RFC 8018, a Password-Based Cryptography Specification (PKCS) is used to generate an encryption key from a given password. The main advantage of using password-based encryption is improved security. As a password set by the owner of the data, it adds another layer of security.

PKCS requires the following inputs to generate a unique encryption key:

  • Password, it is provided by the owner of the data.
  • The salt value, it should be at least 64 bits (8 bytes) long.
  • Iteration Count.

What are Salt value and Iteration count?

The salt value is a random set of keys generated to increase the security for a given password. For instance, for a 128 bits salt value, there will be maximum 2^128 keys for each password. Therefore, it makes it more difficult to hack in case of an attack.

The iteration count also serves a similar purpose of providing more security, it increases the cost of generating keys from a password, therefore increasing difficulty and time that would be needed during attacks. A recommended Iteration count would be at least 1000 but it can be increased depending on the required level of security.

See Also: Java Security Vulnerabilities: Case Commentary

A class in Java called SecretKeyFactory is used along with the algorithm called “PBKDF2WithHmacSHA256” for generating a key from a given password.

The code snippet below shows the definition of a function called getKeyFromPassword that generates the AES key from a given password. Here 80,000 iterations and a key length of 128 bits are used,

1.	public static SecretKey getKeyFromPassword(String password, String salt)
2.	throws NoSuchAlgorithmException, InvalidKeySpecException {
3.	SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
4.	KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), 80000, 128);
5.	SecretKey secret = new SecretKeySpec(factory.generateSecret(spec)
6.	getEncoded(), "AES");
7.	return secret;
8.	}

Conclusion

AES Java provides a wide range of modes and features for encryption of numerous types of data. It offers authenticity and integrity for encrypted data, Parallel encryption and option for making a cipher stream out of a cipher block. All these modes make it very convenient for java developers to encrypt the data as per their requirements and type of data.

Author

Shaharyar Lalani is a developer with a strong interest in business analysis, project management, and UX design. He writes and teaches extensively on themes current in the world of web and app development, especially in Java technology.

Write A Comment