Production-ready hybrid encryption middleware for Express.js with RSA-OAEP + AES-256-GCM
npm install hybrid-encryption-expressbash
npm install @your-scope/hybrid-encryption-express
`
Quick Start
$3
`javascript
import express from 'express';
import {
createHybridCrypto,
hybridDecryptMiddleware,
hybridEncryptMiddleware,
cryptoRouter
} from '@your-scope/hybrid-encryption-express';
const app = express();
const hybridCrypto = createHybridCrypto();
// Middleware setup
app.use(express.json());
app.use(hybridDecryptMiddleware({ hybridCrypto }));
app.use(hybridEncryptMiddleware({ hybridCrypto }));
// Crypto routes for handshake
app.use(cryptoRouter({ hybridCrypto }));
// Your protected routes
app.post('/api/data', (req, res) => {
// req.body is automatically decrypted
// Response will be encrypted if X-Encrypted: true header is present
res.json({ message: 'Data received', data: req.body });
});
app.listen(3000);
`
$3
`typescript
import express, { Request, Response } from 'express';
import {
createHybridCrypto,
hybridDecryptMiddleware,
hybridEncryptMiddleware,
cryptoRouter,
type HybridCryptoOptions
} from '@your-scope/hybrid-encryption-express';
const options: HybridCryptoOptions = {
sessionTtlMs: 10 60 1000, // 10 minutes
skipRoutes: ['/health', '/public']
};
const app = express();
const hybridCrypto = createHybridCrypto(options);
app.use(express.json());
app.use(hybridDecryptMiddleware({ hybridCrypto }));
app.use(hybridEncryptMiddleware({ hybridCrypto }));
app.use(cryptoRouter({ hybridCrypto }));
app.post('/api/secure', (req: Request, res: Response) => {
// TypeScript knows about req.encryptionMetadata
if (req.encryptionMetadata?.encrypted) {
console.log('Request was encrypted');
}
res.json({ secure: true, data: req.body });
});
`
Client Integration
$3
`javascript
const response = await fetch('/crypto/public-key');
const { publicKey } = await response.json();
`
$3
`javascript
import { createPublicKey, publicEncrypt, randomBytes } from 'crypto';
// Generate AES-256 key
const aesKey = randomBytes(32);
// Encrypt AES key with RSA public key
const publicKeyObj = createPublicKey(publicKey);
const encryptedAesKey = publicEncrypt({
key: publicKeyObj,
padding: 1, // RSA_PKCS1_OAEP_PADDING
oaepHash: 'sha256'
}, aesKey);
// Perform handshake
const handshakeResponse = await fetch('/crypto/handshake', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
clientId: 'unique-client-id',
encryptedAesKey: encryptedAesKey.toString('base64')
})
});
const { success, sessionExpiry } = await handshakeResponse.json();
`
$3
`javascript
import { createCipherGCM, randomBytes } from 'crypto';
function encryptData(data, aesKey) {
const iv = randomBytes(12);
const cipher = createCipherGCM('aes-256-gcm', aesKey);
let encrypted = cipher.update(JSON.stringify(data), 'utf8');
encrypted = Buffer.concat([encrypted, cipher.final()]);
return {
data: encrypted.toString('base64'),
iv: iv.toString('base64'),
authTag: cipher.getAuthTag().toString('base64')
};
}
// Send encrypted request
const encryptedPayload = encryptData({ message: 'secret data' }, aesKey);
const response = await fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Client-Id': 'unique-client-id',
'X-Encrypted': 'true'
},
body: JSON.stringify(encryptedPayload)
});
`
API Reference
$3
Creates a new HybridCrypto instance.
Options:
- sessionStore?: SessionStore - Custom session store (default: MemorySessionStore)
- sessionTtlMs?: number - Session TTL in milliseconds (default: 5 minutes)
- rsaKeySize?: number - RSA key size (default: 2048)
- skipRoutes?: string[] - Routes to skip encryption (default: ['/health', '/crypto/public-key', '/crypto/handshake'])
$3
Express middleware for decrypting incoming requests.
Options:
- hybridCrypto: HybridCrypto - HybridCrypto instance
- skipRoutes?: string[] - Routes to skip decryption
- clientIdHeader?: string - Header name for client ID (default: 'x-client-id')
$3
Express middleware for encrypting outgoing responses.
Options:
- hybridCrypto: HybridCrypto - HybridCrypto instance
- skipRoutes?: string[] - Routes to skip encryption
- encryptHeader?: string - Header to check for encryption request (default: 'x-encrypted')
$3
Express router with crypto endpoints.
Options:
- hybridCrypto: HybridCrypto - HybridCrypto instance
- publicKeyPath?: string - Public key endpoint path (default: '/crypto/public-key')
- handshakePath?: string - Handshake endpoint path (default: '/crypto/handshake')
- testPath?: string - Test endpoint path (default: '/crypto/test')
Custom Session Store
Implement the SessionStore interface for custom storage:
`typescript
import { SessionStore, SessionData } from '@your-scope/hybrid-encryption-express';
class RedisSessionStore implements SessionStore {
async set(clientId: string, sessionData: SessionData): Promise {
// Store in Redis
}
async get(clientId: string): Promise {
// Retrieve from Redis
}
async delete(clientId: string): Promise {
// Delete from Redis
}
async cleanup(): Promise {
// Clean expired sessions
}
}
``