Securing Spring Cloud Gateway with RSA, Timestamp and Signature Verification

This guide explains how to protect a Spring Cloud Gateway service from packet sniffing by using RSA asymmetric encryption, timestamp validation, unique request IDs stored in Redis, and MD5 signature checks, with complete Java and front‑end code examples.

IT Architects Alliance
IT Architects Alliance
IT Architects Alliance
Securing Spring Cloud Gateway with RSA, Timestamp and Signature Verification

RSA Asymmetric Encryption Overview

RSA is a public‑key algorithm whose security relies on the difficulty of factoring large integers. The example uses a 1024‑bit key pair generated with the JCE API.

Java RSA Utility (RSAUtils)

Provides methods to generate a key pair, encrypt a UTF‑8 string with a Base64‑encoded public key, and decrypt a Base64‑encoded ciphertext with a private key. It uses KeyPairGenerator, Cipher, and Apache Commons Codec for Base64 handling.

public static Map<String,String> generateRasKey() { /* generate 1024‑bit RSA key pair */ }
public static String encrypt(String plain, String publicKey) { /* RSA encryption, return Base64 string */ }
public static String decrypt(String cipherText, String privateKey) { /* RSA decryption, return plain text */ }

Custom Exception

public class RsaException extends RuntimeException { private final String message; public RsaException(String message) { this.message = message; } }

Unit Tests

Demonstrate key generation, encryption of a JSON payload, and decryption of a sample ciphertext.

@Test public void generateRsaKey() { Map<String,String> map = RSAUtils.generateRasKey(); System.out.println(map.get(RSAUtils.PUBLIC_KEY)); System.out.println(map.get(RSAUtils.PRIVATE_KEY)); }
@Test public void testEncrypt() { JSONObject obj = new JSONObject(); obj.put("username","rosh"); obj.put("password","123456"); String data = obj.toJSONString(); String encrypt = RSAUtils.encrypt(data, PUBLIC_KEY); System.out.println(encrypt); }
@Test public void testDecrypt() { String decrypt = RSAUtils.decrypt("Yeidauky/...", PRIVATE_KEY); System.out.println(decrypt); }

Front‑End Encryption and Request Signing

The login page loads jQuery, jsencrypt and md5. The public key is set in JSEncrypt. Before sending a request the form data is:

Sorted by ASCII key order.

Serialized to JSON.

Signed with MD5 over json + requestId + timestamp.

Encrypted with RSA.

Sent as the request body with HTTP headers timestamp, requestId and sign.

var encrypt = new JSEncrypt();
encrypt.setPublicKey("MIGfMA0G...");
var data = JSON.stringify(sort_ASCII(form));
var timestamp = Date.now();
var requestId = getUuid();
var sign = MD5(data + requestId + timestamp);
$.ajax({
    url: "/api/user/login",
    type: "POST",
    data: encrypt.encrypt(data),
    beforeSend: function(xhr){
        xhr.setRequestHeader("timestamp", timestamp);
        xhr.setRequestHeader("requestId", requestId);
        xhr.setRequestHeader("sign", sign);
    },
    contentType: "application/json;charset=utf-8"
});

The query page follows the same pattern, encrypting the query string and adding the same three headers.

Spring Cloud Gateway Global Filter

A GatewayFilterConfig implements GlobalFilter and performs the following steps for every request:

Extract and validate timestamp (must be within 5 minutes).

Extract and validate requestId (must be unique for 5 minutes, stored in Redis).

Extract the MD5 sign header.

For non‑login URLs, verify the JWT token.

Decrypt the RSA‑encrypted request body using the private key.

Merge decrypted JSON fields with query parameters (if a param query parameter is present).

Re‑compute the MD5 signature over the merged parameters, requestId and timestamp; reject the request if the signatures differ.

Wrap the modified request in a ServerHttpRequestDecorator that supplies the decrypted body to downstream handlers.

Key Helper Methods

private Long getDateTimestamp(HttpHeaders headers) { /* parse, check 5‑minute window, throw if invalid */ }
private String getRequestId(HttpHeaders headers) { /* read, check Redis for replay, store for 5 min, throw if invalid */ }
private String getSign(HttpHeaders headers) { /* read sign header, throw if missing */ }
private void checkSign(String sign, Long timestamp, String requestId, Map<String,Object> params) { /* compute MD5 and compare, throw if mismatch */ }

Cached Body Output Message

The custom MyCachedBodyOutputMessage extends CachedBodyOutputMessage and stores the decrypted parameter map, requestId, sign and timestamp for later verification.

public void initial(Map<String,Object> paramMap, String requestId, String sign, Long dateTimestamp) { this.paramMap = paramMap; this.requestId = requestId; this.sign = sign; this.dateTimestamp = dateTimestamp; }

Back‑End Controllers and Service

A simple UserController provides /login and /detail endpoints. The login method checks hard‑coded credentials ( admin / 123456) and returns a JWT token. The detail method returns a JSON object with user information.

Repository

https://gitee.com/zhurongsheng/springcloud-gateway-rsa
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.

JavaredisSecurityRSAtimestampsignatureSpring Cloud Gateway
IT Architects Alliance
Written by

IT Architects Alliance

Discussion and exchange on system, internet, large‑scale distributed, high‑availability, and high‑performance architectures, as well as big data, machine learning, AI, and architecture adjustments with internet technologies. Includes real‑world large‑scale architecture case studies. Open to architects who have ideas and enjoy sharing.

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.