@newput-newlink/security v1.0.4
Encryption Middleware for NestJS šš Overview This module implements Hybrid Encryption in a NestJS middleware, ensuring that all incoming requests are decrypted and outgoing responses are encrypted using a combination of RSA and AES encryption.
š¹ Features ā Hybrid Encryption (RSA + AES-256-GCM) for speed and security ā Seamless Middleware Integration in NestJS ā Automatic Encryption & Decryption of request/response payloads ā Prevents Recursive Encryption for multiple middleware layers ā Tamper-proof Authentication Tag (authTag) for AES encryption
1ļøā£ Installation First, install the required dependencies:
sh Copy Edit npm install crypto 2ļøā£ How It Works š¹ Hybrid Encryption (RSA + AES) Flow 1ļøā£ Client-Side Encryption
Generates a random AES key & IV (Initialization Vector) Encrypts the data using AES-256-GCM Encrypts the AES key using RSA Public Key Sends { encryptedData, iv, authTag, encryptedAESKey } in the request 2ļøā£ Middleware Decryption (Server-Side)
Decrypts the AES key using RSA Private Key Uses the AES key to decrypt encryptedData Ensures integrity using authTag Processes the decrypted request 3ļøā£ Server-Side Response Encryption
Generates a new AES key & IV Encrypts the response with AES-256-GCM Encrypts the AES key using RSA Public Key Sends { encryptedData, iv, authTag, encryptedAESKey } back to the client 3ļøā£ Middleware Usage š Step 1: Register Middleware In your app.module.ts, apply the middleware globally:
ts Copy Edit import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'; import { EncryptionMiddleware } from './encryption.middleware';
@Module({}) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(EncryptionMiddleware).forRoutes('*'); // Apply to all routes } } 4ļøā£ Configuration š Step 2: Provide RSA Keys Your RSA keys must be stored securely. Configure them in an environment file or pass them dynamically:
ts Copy Edit { rsaConfig: { privateKey: process.env.RSA_PRIVATE_KEY, // Keep this secret publicKey: process.env.RSA_PUBLIC_KEY // Used for encryption } } 5ļøā£ Encryption & Decryption Logic š Encrypting Data (AES + RSA) ts Copy Edit encryptData(data: string): { encryptedData: string; iv: string; authTag: string; encryptedAESKey: string } { const aesKey = crypto.randomBytes(32); // AES-256 key const iv = crypto.randomBytes(16); // IV for AES-GCM
const cipher = crypto.createCipheriv('aes-256-gcm', aesKey, iv); let encrypted = cipher.update(data, 'utf8', 'base64'); encrypted += cipher.final('base64');
const encryptedAESKey = crypto.publicEncrypt( { key: this.publicKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, }, aesKey );
return { encryptedData: encrypted, iv: iv.toString('base64'), authTag: cipher.getAuthTag().toString('base64'), encryptedAESKey: encryptedAESKey.toString('base64') }; } š Decrypting Data (RSA + AES) ts Copy Edit decryptData(encryptedPayload: { encryptedData: string; iv: string; authTag: string; encryptedAESKey: string }): string { const { encryptedData, iv, authTag, encryptedAESKey } = encryptedPayload;
const decryptedAESKey = crypto.privateDecrypt( { key: this.privateKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, }, Buffer.from(encryptedAESKey, 'base64') );
const decipher = crypto.createDecipheriv('aes-256-gcm', decryptedAESKey, Buffer.from(iv, 'base64')); decipher.setAuthTag(Buffer.from(authTag, 'base64'));
let decrypted = decipher.update(encryptedData, 'base64', 'utf8'); decrypted += decipher.final('utf8');
return decrypted; } 6ļøā£ Example Request & Response Format š Encrypted Request (Client to Server) json Copy Edit { "encryptedData": "mYF83Vh+...", "iv": "sdfu8JKo...", "authTag": "0gA6X9ft...", "encryptedAESKey": "L2mp5JTo..." } š Encrypted Response (Server to Client) json Copy Edit { "encryptedData": "mR4T3Dd+...", "iv": "Kjs73Dpd...", "authTag": "1qX9H2ba...", "encryptedAESKey": "R2nd7LPo..." } 7ļøā£ Security Best Practices ā š Keep the RSA private key secure (never expose it in frontend or logs). š Rotate AES keys periodically to enhance security. ā ļø Validate decrypted data before processing to avoid attacks. š Store encryption logs securely to debug potential failures.