AES Encryption and Decryption Logic


This document explains the logic behind using AES (Advanced Encryption Standard) for secure data transmission, particularly in encrypting and decrypting data, with a symmetric key. We’ll cover how AES encryption in CBC mode with PKCS5 padding is implemented and used for secure data transmission. Below are the main components involved in the process, along with a sample Java code implementation.

Process Flow

Encryption:

  1. Decode the Base64-encoded symmetric key.
  2. Generate a random IV.
  3. Encrypt the data using the decoded key and IV.
  4. Combine the IV and the encrypted data into one payload.
  5. Encode the final output with Base64 for transmission.

 

Decryption:

  1. Decode the Base64-encoded input (both IV and ciphertext).
  2. Extract the IV from the first part of the input.
  3. Decrypt the remaining ciphertext using the same key and extracted IV.
  4. Remove any extraneous noise (if applicable) after decryption, ensuring the output is in the expected format.

 

Handling Noise in Decrypted Data

In cases where noise or extra characters may be present after decryption (e.g., due to system-specific formatting issues), it's crucial to clean the decrypted data. This can be done by identifying and preserving the structure of the original payload, such as JSON objects or arrays.

 

Sample Java Code Implementation:


Below is a sample implementation of the AES encryption and decryption logic in Java:

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Arrays;
import java.nio.charset.StandardCharsets;
public class AESUtils {
// —------- Encryption Method —-----------
public static String EncryptRequest(Object incomingJsonReq,
String key) throws Exception {
byte[] decodedKey = Base64.getDecoder().decode(key);
if (decodedKey.length != 32) {
throw new IllegalArgumentException("Invalid key");
}
// Generate a random IV
byte[] iv = new byte[16];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
System.out.println("IV generated: " + Arrays.toString(iv));
// Convert payload to byte array
byte[] payloadBytes = incomingJsonReq.toString().getBytes();
// Initialize AES cipher
SecretKeySpec secretKeySpec = new SecretKeySpec(decodedKey,"AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
// Encrypt the data
byte[] encryptedBytes = cipher.doFinal(payloadBytes);
// Combine IV and encrypted data
byte[] result = new byte[iv.length + encryptedBytes.length];
System.arraycopy(iv, 0, result, 0, iv.length);
System.arraycopy(encryptedBytes, 0, result, iv.length,encryptedBytes.length);
// Return Base64 encoded result
return Base64.getEncoder().encodeToString(result);
}
// —-------- Decryption Method -----------
public String decryptRequest(String encryptedString, String key)
throws Exception {
// Decode Base64 encoded input and key
byte[] byteCipherText = Base64.getDecoder().decode(encryptedString);
byte[] byteKey = Base64.getDecoder().decode(key);
// Extract IV and cipher text from the encrypted input
byte[] iv = Arrays.copyOfRange(byteCipherText, 0, 16);
byte[] cipherText = Arrays.copyOfRange(byteCipherText, 16, byteCipherText.length);
// Initialize AES cipher for decryption
SecretKeySpec secretKey = new SecretKeySpec(byteKey, "AES");
IvParameterSpec ivParams = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParams);
// Decrypt the cipher text
byte[] bytePlainText = cipher.doFinal(cipherText);
// Clean the decrypted data and return
return removeNoise(new String(bytePlainText, StandardCharsets.UTF_8).trim());
}
// Removing noise and returning clean string up to } or ]
private String removeNoise(String data) {
int lastCurlyBrace = data.lastIndexOf('}');
int lastSquareBracket = data.lastIndexOf(']');
int lastIndex = Math.max(lastCurlyBrace, lastSquareBracket);
if (lastIndex != -1) {
return data.substring(0, lastIndex + 1);
}
return data;
}
}

 

Conclusion:

The logic explained in this document enables secure encryption and decryption of data using AES in CBC mode. By combining proper key management, secure IV generation, and Base64 encoding for transmission, the method ensures the confidentiality of sensitive information.

Notes:

  • This algorithm allows JSON and array of JSON for decryption.
  • Any file in the payload is to be passed on as it is.