Table of Contents
Introduction
Advanced encryption standard (AES) is the most secure encryption standard compared to RSA, which is vulnerable to brute force attacks.
This is the main reason that AES was established by the National Institute of Standard and Technology (NIST) in 2001 and is used worldwide to date.
In the previous post, we have seen how to implement AES 128 encryption and decryption algorithm. In this tutorial, you will learn how to encrypt and decrypt data using AES 256
, which works the same way as AES 128
with few minor changes, and its implementation has been covered in another tutorial.
When working with AES, we have to provide three inputs that will be used in the encryption process, and they include the message, secret key, an initialization vector (IV).
The block cipher algorithm uses permutations to process the data, and the more the key size, the more the permutations.
AES 256
algorithm takes a 128-bit input data and processes it in 14
rounds, and with the possibility of breaking the AES algorithm being feasible, the use of AES 256
is considered compared to 128
and 192
as it requires high computing power to exploit which most users do not have.
We can use several ways to generate a key in java, and we will see the getInstance()
method of the KeyGenerator
class in java.
The method accepts a string representing the algorithm to be used in the encryption and decryption process, and we only need to pass string AES
as the parameter.
This class will create an instance of the RSA
transformation with a default key length of 128
bits. However, we want our algorithm to use a key length of 256
bits and to achieve this call the init()
method from the KeyGenerator
object we have just created and pass an in value of 256
.
The generateKey()
method will return a SecretKey
, a Key
that we will use to encrypt and decrypt because it is shared in both functionalities.
Convert the generated key to string using the encodeToString()
method of Base64.Encoder
and log the result to the console to verify that the key was generated.
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 AES256Encryption { public static void main(String[] args) throws NoSuchAlgorithmException { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(256); SecretKey secretKey = keyGenerator.generateKey(); String secretKeyString = Base64.getEncoder().encodeToString(secretKey.getEncoded()); System.out.println("generated key = "+secretKeyString); } } |
Output:
Further reading:
Encrypt a random text
Create a Cipher
object using the getInstance()
method and pass AES/CBC/PKCS5Padding
, representing the transformation we want to perform.
There are other forms of modes and padding that can be used with the AES transformation, and to achieve this, you can have a look at Java Security Standard Algorithm Names Specification
Since we are using cipher block chaining mode, we need to provide an initialization vector. To achieve this, create IvParameterSpec
object and pass a new array of bytes of size 16
to its constructor.
The byte array of size 16
makes it equal to a block size of 128
bits, and you should create a new one when working with a different message.
Call the init()
method of the cipher object and pass Cipher.ENCRYPT_MODE
to indicate that we want to encrypt a message, the SceretKey
we generated, and the IvParameterSpec
object.
The doFinal()
method encrypts the message and returns an array of bytes that we convert to a string and log to the console to verify that the message was encrypted.
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 AES256Encryption { public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(256); 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"); IvParameterSpec parameterSpec = new IvParameterSpec(new byte[16]); 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 = 8cOldh6oBNdzn6ah6iz+hg==
Decrypt the encrypted text
To decrypt the encrypted text, we only need to create a new Cipher
object as we did when encrypting a message and call the init()
method.
The only method parameter that changes is the mode since we are performing decryption, and the first parameter should be changed to Cipher.DECRYPT_MODE
.
When we call the doFinal()
method and pass the encrypted message, it decrypts and returns an array of bytes.
The data returned represents bytes of our decrypted message, and we can convert the message to a string by creating a new string object and passing it to the constructor.
To verify that our message was decrypted print the results of the new string to the console, and you will see the original message that we created.
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 |
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 AES256Encryption { public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(256); 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"); IvParameterSpec parameterSpec = new IvParameterSpec(new byte[16]); 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 = 8cOldh6oBNdzn6ah6iz+hg==
decrypted message =Hello world
Conclusion
In this tutorial, you have learned how to encrypt and decrypt a random text using AES 256
, a popular encryption standard used worldwide. You have also learned how to add a custom key size using the init()
method of the KeyGenerator
, and this method also works for 128
and 192
key sizes. Feel free to check out the other articles on AES
and RSA
encryption and decryption to learn how they work.