Data encryption is an important feature to assure the safety of data transmitted. While there are many ways to do it, in this article we’ll see how implement AES encryption and decryption in Java.
Overview on AES Algorithm
AES is a symmetric encryption method, meaning it uses the same key to encrypt data as it does to decrypt data. AES takes a block of plain text and applies alternating rounds of substitution and permutation boxes to the passage. This form of encryption is known as a substitution permutation network (SPN) block cipher algorithm, and the size of the boxes alternate between 128, 192 or 256 bits, depending on the strength of encryption.
AES can be used with different modes of operation, such as Electronic Codebook (ECB), Cipher Block Chaining (CBC), Galois/Counter Mode (GCM), and others, to address various encryption requirements.
Java AES Encryption and Decryption Example
For the following example, we’ll use AES CBC mode and the standard Java Cryptography Extension (JCE) library.
public class AESUtil { private static final String ALGORITHM = "AES"; private static final String TRANSFORMATION = "AES/CBC/PKCS5PADDING"; private static final String KEY = "aesEncryptionKey"; private static final int IV_LENGTH = 16; public SecretKeySpec hashKey() throws NoSuchAlgorithmException, UnsupportedEncodingException { MessageDigest digest = MessageDigest.getInstance("SHA-256"); digest.update(KEY.getBytes("UTF-8")); byte[] keyBytes = new byte[IV_LENGTH]; System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length); return new SecretKeySpec(keyBytes, ALGORITHM); } public String encrypt(String plainValue) throws NoSuchAlgorithmException, UnsupportedEncodingException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { byte[] valueBytes = plainValue.getBytes(); // Generate IV. byte[] iv = new byte[IV_LENGTH]; SecureRandom random = new SecureRandom(); random.nextBytes(iv); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); // Hash key. SecretKeySpec secretKeySpec = hashKey(); // Encrypt. Cipher cipher = Cipher.getInstance(TRANSFORMATION); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] encrypted = cipher.doFinal(valueBytes); // Combine IV and encrypted part. byte[] encryptedIVAndText = new byte[IV_LENGTH + encrypted.length]; System.arraycopy(iv, 0, encryptedIVAndText, 0, IV_LENGTH); System.arraycopy(encrypted, 0, encryptedIVAndText, IV_LENGTH, encrypted.length); return Base64.getEncoder().encodeToString(encryptedIVAndText); } public String decrypt(String encrypted) throws NoSuchAlgorithmException, UnsupportedEncodingException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { byte[] encryptedIvTextBytes = Base64.getDecoder().decode(encrypted); // Extract IV. byte[] iv = new byte[IV_LENGTH]; System.arraycopy(encryptedIvTextBytes, 0, iv, 0, iv.length); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); // Extract encrypted part. int encryptedSize = encryptedIvTextBytes.length - IV_LENGTH; byte[] encryptedBytes = new byte[encryptedSize]; System.arraycopy(encryptedIvTextBytes, IV_LENGTH, encryptedBytes, 0, encryptedSize); // Hash key. SecretKeySpec secretKeySpec = hashKey(); // Decrypt. Cipher cipherDecrypt = Cipher.getInstance(TRANSFORMATION); cipherDecrypt.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] decrypted = cipherDecrypt.doFinal(encryptedBytes); return new String(decrypted); } }
The hashkey method is used to hash the AES key using the SHA-256 algorithm.
In the encrypt method we first generate a random IV then we hash the key. For CBC mode the IV mode should be randomized, its use is to prevent the same plain text block producing the same cipher text every time. Then we encrypt the data and return it.
In the decrypt method we first grab the IV from the front of the encrypted data then we hash the key again. Finally we decrypt the value and return it.
Conclusion
With a few lines we’ve built a class for encrypting and decrypting data for any use. AES Java provides a wide range of modes and features for encryption of numerous types of data, and it makes easy to develop robust solutions to secure data. The source project is available on GitHub.