Table of Contents
Introduction
AES stands for advanced encryption standard and is the most commonly used symmetric algorithm to encrypt sensitive data and can be used in both software and hardware.
The AES algorithm is symmetric, meaning that it uses only one key for encryption and decryption, and due to this reason, the key must be shared between the sender and the receiver.
The standard has three key sizes, which include 128, 192, and 256 and each of the ciphers encrypts and decrypts data in blocks of 128 bits.
The key sizes perform 10, 12, and 14 rounds on the data for 128, 192, and 256 respectively, making 256 the stronger algorithm among them.
By default, the java implementation of the AES algorithm uses 128 key size, and in this tutorial, we will implement the algorithm to encrypt and decrypt a message.
To generate a key that will be used for both encryption and decryption of our message, we will use the getInstance() method of the KeyGenerator class in java and pass string AES to the method.
The getInstance() method throws a NoSuchAlgorithmException if no provider supports a KeyGeneratorSpi of the specified algorithm and a NullPointerException if the algorithm provided is null.
The KeyGenerator will create an instance of the AES algorithm that we will use to generate a key using the generateKey() method of the class.
This class generates a symmetric secret key, and once a key has been generated, the same object can be used to create other keys.
Use the encodeToString() method of Base64.Encoder to view the generated string of the key by logging the result to the console.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package com.encryption; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import java.security.NoSuchAlgorithmException; import java.util.Base64; public class AESEncryption { public static void main(String[] args) throws NoSuchAlgorithmException { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); SecretKey secretKey = keyGenerator.generateKey(); String secretKeyString = Base64.getEncoder().encodeToString(secretKey.getEncoded()); System.out.println("generated key = "+secretKeyString); } } |
Output:
Further reading:
Encrypt a random text
To encrypt the message, create a Cipher object and use the getInstance() with parameter AES/CBC/PKCS5Padding as the transformation to create an instance of the algorithm.
The transformation has a mode and padding, and in our case, we will use CBC mode, which stands for cipher block chaining, and PKCS5Padding as the padding.
The default mode is ECB, but since it does not support multiple blocks of data, we will use CBC, which is a mode of operation for a block cipher.
The cipher block chaining mode uses an initialization vector, also known as IV, which is an input to the cryptographic algorithm used to provide the initial state and requires to be unique.
The padding is introduced to the algorithm so that if the string to be encrypted is not an exact multiple of the block size, then padding is done before encrypting by adding a padding string.
Since we will provide an initialization vector to the init() method of the Cipher create IvParameterSpec class and pass the key bytes to its constructor, which be used as the initialization vector.
Call the init() method and pass Cipher.ENCRYPT_MODE, SecretKey and finally the IvParameterSpec object created.
Create a random text and call the doFinal() method of the Cipher and pass the message bytes to the method to perform encryption.
The doFinal() method returns an array of bytes containing the encrypted message, and we can convert the bytes to string using the encodeToString() method and log its content to the console to verify that the encryption was successful.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
package com.encryption; import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Base64; public class AESEncryption { public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); SecretKey secretKey = keyGenerator.generateKey(); String secretKeyString = Base64.getEncoder().encodeToString(secretKey.getEncoded()); System.out.println("generated key = "+secretKeyString); //Encrypt Hello world message Cipher encryptionCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); byte[] InitVectorBytes = keyGenerator.generateKey().getEncoded(); IvParameterSpec parameterSpec = new IvParameterSpec(InitVectorBytes); encryptionCipher.init(Cipher.ENCRYPT_MODE,secretKey,parameterSpec); String message = "Hello world"; byte[] encryptedMessageBytes = encryptionCipher.doFinal(message.getBytes()); String encryptedMessage = Base64.getEncoder().encodeToString(encryptedMessageBytes); System.out.println("Encrypted message = "+encryptedMessage); } } |
Output:
Encrypted message = /PLOtvd+J/7KLGOdPaVZtg==
Decrypt the encrypted text
Since we already have an initialization vector and a secret key, we need to create a new Cipher object as we did previously and use the AES/CBC/PKCS5Padding transformation in the getInstance() method.
The only parameter of the init() method that changes is the mode as we are performing a decryption operation, and we need to pass Cipher.DECRYPT_MODE as the first parameter of the method.
Convert the bytes returned by the doFinal() method to a string by passing the returned result to the String() constructor and log to the console to verify that the decrypted message was our original message.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
package org.arpit.java2blog; import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Base64; public class AESEncryption { public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); SecretKey secretKey = keyGenerator.generateKey(); String secretKeyString = Base64.getEncoder().encodeToString(secretKey.getEncoded()); System.out.println("generated key = "+secretKeyString); //Encrypt Hello world message Cipher encryptionCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); byte[] InitVectorBytes = keyGenerator.generateKey().getEncoded(); IvParameterSpec parameterSpec = new IvParameterSpec(InitVectorBytes); encryptionCipher.init(Cipher.ENCRYPT_MODE,secretKey,parameterSpec); String message = "Hello world"; byte[] encryptedMessageBytes = encryptionCipher.doFinal(message.getBytes()); String encryptedMessage = Base64.getEncoder().encodeToString(encryptedMessageBytes); System.out.println("Encrypted message = "+encryptedMessage); //Decrypt the encrypted message Cipher decryptionCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); decryptionCipher.init(Cipher.DECRYPT_MODE,secretKey,parameterSpec); byte[] decryptedMessageBytes = decryptionCipher.doFinal(encryptedMessageBytes); String decryptedMessage = new String(decryptedMessageBytes); System.out.println("decrypted message ="+decryptedMessage); } } |
Output:
Encrypted message = /PLOtvd+J/7KLGOdPaVZtg==
decrypted message =Hello world
Conclusion
In this tutorial, you have learned how to encrypt and decrypt a random text using the symmetric AES algorithm with a single key generated using the KeyGenerator class in java. You have also learned how to provide an initialization vector for the CBC mode of the transformation by using the IvParameterSpec provided by the Java API. In the next tutorial, you will learn how to encrypt and decrypt a message using AES 256, which is more resistant to attacks compared to AES 128 and AES 192.