Secure Spring Boot API Data Transmission with AES/RSA Hybrid Encryption

This article explains how to protect front‑end and back‑end communication in a Spring Boot application by encrypting request and response data using a hybrid AES and RSA scheme, custom request wrappers, filters, and AOP‑based response encryption, complete with code examples and implementation details.

Architect
Architect
Architect
Secure Spring Boot API Data Transmission with AES/RSA Hybrid Encryption

1. Data Encryption Overview

Ensuring secure data transfer between front‑end and back‑end is essential; while HTTPS provides transport‑level security, additional application‑level encryption can be applied. This guide demonstrates a hybrid encryption design using symmetric AES and asymmetric RSA within a Spring Boot application.

1.1 Encryption Schemes

Symmetric Encryption (AES, DES, etc.) : Fast, uses a shared secret key for both encryption and decryption. Suitable for large payloads.

Asymmetric Encryption (RSA, ECC, etc.) : Uses a public key for encryption and a private key for decryption. Slower, ideal for encrypting the symmetric key.

Hybrid Encryption : Combines both methods—RSA encrypts the AES session key, while AES encrypts the actual data.

1.2 AES Utility Implementation

The AESUtil class provides methods for key generation, encryption, de‑cryption, Base64 conversion, and HexString conversion. Key methods include: getAESKey(int length) – Generates a random alphanumeric AES key. generateRandomAesKeyWithBase64() – Generates a random AES key and returns it in Base64 format. encrypt(byte[] data, byte[] aesKey) and decrypt(byte[] data, byte[] aesKey) – Core AES operations. encryptToBase64(String data, String aesKey) / decryptFromBase64(String data, String aesKey) – AES with Base64 encoding. toHexString(byte[] b) / toBytes(String s) – Convert between byte arrays and hexadecimal strings, useful for GET request parameters.

1.3 RSA Utility Implementation

The RSAUtil class handles key‑pair generation, public‑key encryption, private‑key decryption, and Base64/Hex conversions. Important constants include MAX_ENCRYPT_BLOCK = 117 and MAX_DECRYPT_BLOCK = 128 for 1024‑bit RSA.

2. Request Decryption Design

Decryption is performed in a servlet Filter that wraps the original HttpServletRequest with a custom RequestWrapper. The wrapper copies the request body, allowing it to be read multiple times.

2.1 RequestWrapper Details

Stores the request body in a byte[] field.

Overrides getInputStream() and getReader() to return streams based on the stored copy.

Provides methods to set the body after decryption and to manage additional parameters for GET requests.

Handles multipart requests by converting parameters to JSON and storing them as the body.

2.2 DecryptReplaceStreamFilter Logic

Checks a custom header aksEncrypt to determine whether decryption is required.

For POST requests, reads the JSON body, extracts the encrypted content and RSA‑encrypted aesKey, decrypts the AES key with the server’s RSA private key, then decrypts the payload with AES. The decrypted JSON is set back into the wrapper.

For GET requests, reads the encryptData parameter (hex‑encoded) and the RSA‑encrypted AES key from the header, performs the same RSA‑then‑AES decryption, and stores the resulting parameters in the wrapper’s parameter map.

Ensures the filter runs before other business logic by registering it with the highest order.

3. Response Encryption Design

Response encryption is applied using an AOP advice that intercepts methods annotated with a custom @ResponseEncrypt annotation.

3.1 Annotation

The @ResponseEncrypt annotation marks controller methods whose return values should be encrypted.

3.2 AOP Implementation

The advice runs with @Order(0) so it executes last, after all other advices.

It retrieves the AES key supplied by the client (e.g., as a request parameter), encrypts the method’s return value with AESUtil.encryptToBase64, and wraps the encrypted string in a standard response object ( R.ok(...)).

4. Testing and Demonstration

Several test classes illustrate the full workflow: TbStudentEntity – Simple POJO used in request/response examples. TbStudentController – Provides /demo/encryptPost and /demo/encryptGet endpoints, both annotated with @ResponseEncrypt. UtilsTestClass – Generates AES keys, RSA key pairs, encrypts sample payloads for POST (Base64) and GET (HexString), and demonstrates decryption of both request and response data.

Filter registration class WebAllHandlerConfig ensures the decryption filter is applied to all URLs.

4.1 Sample Request Flow

For a POST request, the client sends a JSON body containing:

{
  "content": "<em>AES‑encrypted Base64 string</em>",
  "aesKey": "<em>RSA‑encrypted AES key (hex)</em>"
}

The filter decrypts the AES key, then the payload, and the controller receives the original JSON object. The response is then encrypted with the same AES key and returned as Base64.

4.2 Sample GET Request Flow

For a GET request, the encrypted data is passed as a URL parameter encryptData (hex‑encoded) and the RSA‑encrypted AES key is placed in a request header aesKey. After decryption, the controller can access parameters via request.getParameter() or standard @RequestParam annotations.

5. Practical Considerations

Both request and response encryption are optional and controlled by configuration flags and request headers.

Multipart requests require special handling because the wrapper cannot directly read the binary stream; parameters are converted to JSON before decryption.

RSA key size is 1024 bits; the maximum encryptable block size is 117 bytes, and the maximum decryptable block size is 128 bytes.

HexString encoding is used for GET parameters to avoid URL‑unsafe characters such as +, /, and =.

The implementation is framework‑agnostic and can be adapted to other Java web stacks.

By following this guide, developers can add an extra layer of security to their Spring Boot APIs, protecting sensitive data even when HTTPS termination occurs at a load balancer or reverse proxy.

Architecture Diagram
Architecture Diagram
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendSpring BootRSAencryptionAPI SecurityAES
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.