How to Secure Front‑End Data with Hybrid AES‑RSA Encryption: A Complete Guide
In the era of big data and GDPR, front‑end developers must protect personal information beyond HTTPS by using a hybrid AES‑RSA encryption scheme, and this article explains the threats, compares symmetric, asymmetric and hash algorithms, and provides full client‑side and Node.js server implementations with code examples.
Background
In big‑data applications personal data is often collected and transmitted. GDPR requires pseudonymisation and high‑privacy defaults, so front‑end code should avoid sending clear‑text personal data. HTTPS encrypts data in transit, but a malicious browser extension can read the request before encryption, so client‑side encryption is recommended.
Leakage Vectors
Man‑in‑the‑middle (MITM) attacks can intercept traffic; HTTPS mitigates but does not protect data that is already exposed on the client.
Browser extensions can read all network requests and exfiltrate data before HTTPS encryption.
Encryption Primitives
Symmetric encryption (e.g., AES, ChaCha20, 3DES) – fast, single shared key.
Asymmetric encryption (e.g., RSA, ElGamal) – public‑private key pair, suitable for key exchange.
Hash functions (MD4, MD5, SHA families) – used for integrity checks.
Design Options
Pure symmetric encryption – insecure because the key must be delivered to the client.
Pure asymmetric encryption – client encrypts payload with server’s public key; server decrypts with private key. Requires managing two key pairs.
Hybrid encryption – client generates a random symmetric key, encrypts the payload with it, then encrypts the symmetric key with the server’s public key. Server decrypts the symmetric key with its private key and then decrypts the payload. This combines speed of symmetric encryption with secure key exchange.
Chosen Approach
The hybrid scheme (option 3) is implemented in the example.
Client‑Side Implementation (JavaScript)
Libraries: aes-js – AES implementation ( https://github.com/ricmoo/aes-js) jsencrypt – RSA implementation ( https://github.com/travist/jsencrypt)
Workflow:
Generate a random 16‑byte AES key.
Request the server’s RSA public key (GET http://localhost:3000/getPub).
Encrypt the JSON payload with AES.
Encrypt the AES key with the RSA public key.
POST the encrypted payload and encrypted key to http://localhost:3000/login.
Decrypt the server response with the same AES key.
let aesKey = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]; // example random key
let publicKey = "";
window.onload = () => {
axios({method:"GET",url:"http://localhost:3000/getPub"})
.then(result => { publicKey = result.data.data; })
.catch(error => console.log(error));
};
function aesEncrypt(text,key){ /* AES encryption implementation */ }
function aesDecrypt(encryptedHex,key){ /* AES decryption implementation */ }
function submitFn(){
const userName = document.querySelector("#userName").value;
const password = document.querySelector("#password").value;
const data = {userName,password};
const text = JSON.stringify(data);
const sendData = aesEncrypt(text,aesKey);
const encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);
const encryptedKey = encrypt.encrypt(aesKey.toString());
const params = {id:0,data:{param1:sendData,param2:encryptedKey}};
axios({method:"POST",url:"http://localhost:3000/login",data:JSON.stringify(params)})
.then(result => {
const receiveData = aesDecrypt(result.data.data,aesKey);
console.log("Response",receiveData);
})
.catch(error => console.log(error));
}Server‑Side Implementation (Node.js)
Libraries: aes-js ( https://github.com/ricmoo/aes-js) node-rsa ( https://github.com/rzcoder/node-rsa)
Workflow:
Generate an RSA key pair (1024 bits) on startup.
Expose /getPub to return the public key.
Accept POST /login containing param1 (AES‑encrypted payload) and param2 (RSA‑encrypted AES key).
Decrypt the AES key with the RSA private key, then decrypt the payload with that AES key.
Optionally encrypt a response payload with the same AES key and return it.
const http = require("http");
const aesjs = require("aes-js");
const NodeRSA = require("node-rsa");
const rsaKey = new NodeRSA({b:1024});
rsaKey.setOptions({encryptionScheme:"pkcs1"});
let aesKey = null;
let privateKey = "";
http.createServer((request,response)=>{
response.setHeader("Access-Control-Allow-Origin","*");
response.setHeader("Access-Control-Allow-Headers","Content-Type");
response.setHeader("Content-Type","application/json");
if(request.method === "GET" && request.url === "/getPub"){
const publicKey = rsaKey.exportKey("public");
privateKey = rsaKey.exportKey("private");
response.writeHead(200);
response.end(JSON.stringify({result:true,data:publicKey}));
return;
}
if(request.method === "POST" && request.url === "/login"){
let body = "";
request.on("data",chunk=>{body+=chunk;});
request.on("end",()=>{
const params = JSON.parse(body);
const decrypted = rsaKey.decrypt(params.data.param2,"utf8");
aesKey = decrypted.split(",").map(item=>+item);
const decryptedData = aesDecrypt(params.data.param1,aesKey);
// Example response payload
const responseData = aesEncrypt(JSON.stringify({userId:123,address:"Hangzhou"}),aesKey);
response.writeHead(200);
response.end(JSON.stringify({result:true,data:responseData}));
});
return;
}
response.writeHead(404);
response.end();
}).listen(3000);AES Helper Functions
function aesEncrypt(text,key){
const textBytes = aesjs.utils.utf8.toBytes(text);
const aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5));
const encryptedBytes = aesCtr.encrypt(textBytes);
return aesjs.utils.hex.fromBytes(encryptedBytes);
}
function aesDecrypt(encryptedHex,key){
const encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex);
const aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5));
const decryptedBytes = aesCtr.decrypt(encryptedBytes);
return aesjs.utils.utf8.fromBytes(decryptedBytes);
}Result
The client sends only encrypted data; the server receives and processes the ciphertext, then returns an encrypted response. Sensitive fields such as username and password never appear in clear text on the network.
Repository
Full source code:
https://github.com/Pulset/FrontDataEncryptSigned-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
政采云技术
ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
