Java AES Encryption and Decryption
1. AES Algorithm
The AES algorithm (also known as the Rijndael algorithm) is a symmetric-key block cipher that supports cryptographic keys (secret keys) of 128, 192, and 256 bits to encrypt and decrypt data in blocks of 128 bits.
The symmetric-key block cipher plays an important role in data encryption. It means that the same key is used for both encryption and decryption. The Advanced Encryption Standard (AES) is a widely used symmetric-key encryption algorithm. The below figure shows the high-level AES algorithm:
If the data to be encrypted doesn’t meet the block size requirement of 128 bits, it must be padded. Padding is the process of filling up the last block to 128 bits.
2. Modes Of Operation
The AES algorithm has five modes of operation:
- ECB (Electronic Code Book)
- CBC (Cipher Block Chaining)
- CFB (Cipher Feedback)
- OFB (Output Feedback)
- CTR (Counter)
We can apply the mode of operation in order to strengthen the effect of the encryption algorithm. Moreover, the mode of operation may convert the block cipher into a stream cipher. Each mode has its strengths and weaknesses. Let’s quickly review each one.
2.1 ECB
This is the simplest mode of encryption. Each plaintext is divided into blocks with a size of 128 bits and each block is encrypted separately. Similarly, each ciphertext block is decrypted separately. Only issue is that a single key is used to encrypt each block therefore the created ciphertext is not blurred.
2.2 CBC
In order to overcome ECB weakness, CBC mode uses an initialization vector (IV) to augment the encryption. This mode adds XOR to the plaintext and then encrypts the data. The first plaintext block is XOR with Initialization Vector (IV). The IV has the same block size as plaintext. During decryption, the decrypted data is XOR with IV. In this mode, encryption can’t be parallelized, but decryption can be parallelized. It also requires padding data.
2.3 CFB
This is also similar as CBC mode, except that one should encrypt cipher data from previous round, not the plaintext. In this mode, decryption can be parallelized, but encryption can’t be parallelized.
2.4 OFB
This creates keystream bits that are used for encrypting subsequent data blocks. In this regard, the way of working of cipher becomes similar the way of working of typical stream cipher. In OFB mode we can perform both encryption and decryption using only one thread at a time.
2.5 CTR
This is the most popular block cipher modes of operation. In this mode, Both the encryption and decryption can be performed using many threads at a time. The nonce is a unique number used once. It plays the same role as IV. The subsequent values of an increasing counter are added to nonce.
3. AES Parameters
In the AES algorithm, we need three parameters: input data, secret key, and IV. IV is not used in ECB mode.
3.1 Input Data
The input data to the AES can be string, file, object, and password-based.
3.2 Secret Key
There are two ways for generating a secret key in the AES: generating from a random number, or deriving from a given password.
In the first approach, the secret key should be generated from a Cryptographically Secure (Pseudo-)Random Number Generator like the SecureRandom class.
For generating a secret key, we can use the KeyGenerator class. Let’s define a method for generating the AES key with the size of n (128, 192, and 256) bits:
In the second approach, the AES secret key can be derived from a given password using a password-based key derivation function like PBKDF2. We also need a salt value for turning a password into a secret key. The salt is also a random value.
We can use the SecretKeyFactory class with the PBKDF2WithHmacSHA256 algorithm for generating a key from a given password.
Let’s define a method for generating the AES key from a given password with 60,000 iterations and a key length of 256 bits:
3.3 Initialization Vector (IV)
IV is a pseudo-random value and has the same size as the block that is encrypted. We can use the SecureRandom class to generate a random IV.
Let’s define a method for generating an IV:
4. Encryption and Decryption
4.1 String
To implement input string encryption, we first need to generate the secret key and IV according to the previous section. As the next step, we create an instance from the Cipher class by using the getInstance() method.
Additionally, we configure a cipher instance using the init() method with a secret key, IV, and encryption mode. Finally, we encrypt the input string by invoking the doFinal() method. This method gets bytes of input and returns ciphertext in bytes:
For decrypting an input string, we can initialize our cipher using the DECRYPT_MODE to decrypt the content:
Lets write a simple test case to test these encrypt and decrypt method:
4.2 File
The steps are the same, but we need some IO classes to work with the files:
For decrypting a file, we use similar steps and initialize our cipher using DECRYPT_MODE as we saw before.
Now lets write a test for this encryption and decryption methods:
4.3 Object
To encrypt an object we have to use SealedObject class, and the object should be Serializable. Let’s begin by defining a Employee class:
Now lets encrypt this Employee object:
The encrypted object cand be decrypted later by using the same cipher:
Now let’s write a test to demonstrate the encrypt and decrypt methods:
5. Conclusion
In this article, we learned how to encrypt and decrypt input data like strings, files and objects using the AES algorithm in Java. Additionally, we discussed the AES variations.