RSA-AES Hybrid encryption combines RSA-2048 for secure key exchange and AES-256-CBC for high-performance data encryption, providing both the security of asymmetric encryption and the efficiency of symmetric encryption.
RSA-AES Hybrid encryption uses a two-layer approach — asymmetric encryption for securely exchanging a temporary key, and symmetric encryption for fast bulk data encryption. Below is a step-by-step breakdown of the entire process:
A random session key is generated — A fresh 32-byte AES key is created for each request, ensuring every request uses a unique encryption key.
The request data is encrypted — The JSON payload is encrypted using AES-256-CBC with the session key. The first 16 bytes of the session key serve as the IV.
The session key is encrypted — The session key itself is encrypted using the server’s public key with RSA. Only the server can decrypt it using its private key.
The encrypted data is signed — The encrypted data is signed using the client’s private key. This proves the request originated from the client and has not been tampered with.
The payload is sent — The encrypted session key, encrypted data, and signature are combined into a single JSON payload and transmitted to the server.
3. Receiving an Encrypted Response (Server → Client)
When a response is sent back:
The response is encrypted by the server using an AES session key, and the session key is encrypted with the client’s public key — ensuring only the client can decrypt it.
The encrypted data is signed with the server’s private key — allowing the client to verify its authenticity.
The session key is decrypted by the client using the client’s private key.
The signature is verified using the server’s public key to confirm authenticity.
The response data is decrypted using the decrypted session key.
This ensures that every message is confidential (only the intended recipient can read it), authenticated (signed by the sender), and integrity-protected (any tampering invalidates the signature).
An RSA-2048 key pair must be generated on the client side. The client’s public key is to be shared with the server. The client’s private key must be kept secret and securely stored.
import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.SecureRandom;import java.util.Base64;public class GenerateKeys { public static void main(String[] args) throws Exception { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(2048, SecureRandom.getInstanceStrong()); KeyPair keyPair = keyGen.generateKeyPair(); String publicKey = Base64.getEncoder().encodeToString( keyPair.getPublic().getEncoded() ); String privateKey = Base64.getEncoder().encodeToString( keyPair.getPrivate().getEncoded() ); // Share publicKey with the server System.out.println("Client Public Key (share with server): " + publicKey); // Keep privateKey secret System.out.println("Client Private Key (keep secret): " + privateKey); }}
Decrypt Session Key: The encrypted_session_key is decrypted with the client’s private key using RSA/ECB/PKCS1Padding
Verify Signature: The signature is verified against the encrypted_data string using the server’s public key with SHA256withRSA. The response should be rejected if verification fails.
Extract IV: The first 16 bytes of the decrypted session key are used as the IV
Decrypt Data: The encrypted_data is decrypted with AES/CBC/PKCS5Padding using the session key and IV