What is Payload Encryptor?
Payload Encryptor is a secure hybrid encryption library that implements the ECIES (Elliptic Curve Integrated Encryption Scheme) pattern for client-server communication. It provides military-grade encryption with zero configuration.
Whether you're building a banking app, a healthcare platform, or any application that handles sensitive data, Payload Encryptor ensures your data is protected in transit.
Key Features
- 🔐 Two-Way Encryption - Encrypts both requests (client to server) and responses (server to client)
- 🌍 Universal Support - Works in Browsers, Node.js, Bun, Deno, and Cloudflare Workers
- 🔄 Forward Secrecy - Uses new ephemeral keys for every message
- ⚡ Zero Configuration - No complex bundler setup or secrets transmitted over the wire
Security Specifications
Payload Encryptor uses industry-standard cryptographic algorithms:
- Key Exchange: X25519 (Curve25519)
- Encryption: ChaCha20-Poly1305 AEAD
- Key Derivation: HKDF-SHA256
- Authentication: Poly1305 MAC
Only public keys are transmitted - private keys and session keys NEVER leave their respective environments.
Installation
Get started by installing the package:
npm i payload-encryptorOr with other package managers:
bun add payload-encryptor
yarn add payload-encryptorServer-Side Setup
First, let's set up the server. The PayloadServer class handles session creation, decryption of incoming requests, and encryption of responses.
PayloadServer API
static create(): Promise<PayloadServer>- Initialize a server instancecreateSession(): SessionInit- Generate session data (public key) to send to clientdecrypt<T>(payload: EncryptedPayload): T- Decrypt incoming client requestencryptResponse(clientEphemeralPublic: string, data: any): EncryptedResponse- Encrypt response back to client
Server Implementation
import { PayloadServer } from 'payload-encryptor';
// Create the server instance
const server = await PayloadServer.create();
// Endpoint to provide session/public key to client
app.get('/session', () => {
return server.createSession();
});
// Endpoint to receive encrypted data
app.post('/data', async (req) => {
// Get the encrypted payload from request
const encrypted = await req.json();
// Decrypt the client's request
const decrypted = server.decrypt(encrypted);
console.log('Received:', decrypted);
// Process the data and encrypt the response
const response = server.encryptResponse(
encrypted.clientEphemeralPublic,
{ result: 'success', data: 'Your secret response' }
);
return response;
});Client-Side Setup
The PayloadClient class handles session management, encryption of outgoing requests, and decryption of server responses.
PayloadClient API
static create(): Promise<PayloadClient>- Initialize a client instancesetSession(session: SessionInit): void- Set the server's session/public keygetSession(): SessionInit | null- Retrieve current session datahasSession(): boolean- Check if a session is establishedencrypt(payload: string | object): EncryptedPayload- Encrypt a request payloaddecryptResponse<T>(response: EncryptedResponse): T- Decrypt the server's response
Client Implementation
import { PayloadClient } from 'payload-encryptor';
// Create the client instance
const client = await PayloadClient.create();
// Fetch the session from the server
const session = await fetch('/session').then(r => r.json());
// Set the session (server's public key)
client.setSession(session);
// Encrypt your sensitive data
const encrypted = client.encrypt({
data: 'This is my secret message',
userId: 12345
});
// Send the encrypted payload
const encryptedResponse = await fetch('/data', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(encrypted)
}).then(r => r.json());
// Decrypt the server's response
const response = client.decryptResponse(encryptedResponse);
console.log('Server response:', response);Integration with HTTP Libraries
Payload Encryptor works seamlessly with popular HTTP libraries:
With Axios
import axios from 'axios';
import { PayloadClient } from 'payload-encryptor';
const client = await PayloadClient.create();
const session = await axios.get('/session').then(r => r.data);
client.setSession(session);
// Send encrypted request
const response = await axios.post('/data', client.encrypt({
secret: 'my-secret-data'
}));
// Decrypt response
const decrypted = client.decryptResponse(response.data);With Got
import got from 'got';
import { PayloadClient } from 'payload-encryptor';
const client = await PayloadClient.create();
const session = await got('/session').json();
client.setSession(session);
// Send encrypted request
const response = await got.post('/data', {
json: client.encrypt({ secret: 'data' })
}).json();
// Decrypt response
const decrypted = client.decryptResponse(response);With WebSockets
import { PayloadClient } from 'payload-encryptor';
const client = await PayloadClient.create();
const ws = new WebSocket('wss://example.com/socket');
// After receiving session from server
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'session') {
client.setSession(data.session);
} else if (data.type === 'encrypted') {
const decrypted = client.decryptResponse(data.payload);
console.log('Received:', decrypted);
}
};
// Send encrypted message
function sendSecure(data: any) {
const encrypted = client.encrypt(data);
ws.send(JSON.stringify({ type: 'encrypted', payload: encrypted }));
}Complete Example: Secure API
Here's a complete example showing both server and client working together:
Server (Express.js)
import express from 'express';
import { PayloadServer } from 'payload-encryptor';
const app = express();
app.use(express.json());
const server = await PayloadServer.create();
app.get('/api/session', (req, res) => {
res.json(server.createSession());
});
app.post('/api/login', (req, res) => {
const { username, password } = server.decrypt(req.body);
// Validate credentials (example)
if (username === 'admin' && password === 'secret') {
const response = server.encryptResponse(
req.body.clientEphemeralPublic,
{ success: true, token: 'jwt-token-here' }
);
res.json(response);
} else {
const response = server.encryptResponse(
req.body.clientEphemeralPublic,
{ success: false, error: 'Invalid credentials' }
);
res.status(401).json(response);
}
});
app.listen(3000);Client (Browser)
import { PayloadClient } from 'payload-encryptor';
async function secureLogin(username: string, password: string) {
const client = await PayloadClient.create();
// Get session
const session = await fetch('/api/session').then(r => r.json());
client.setSession(session);
// Encrypt credentials
const encrypted = client.encrypt({ username, password });
// Send encrypted login request
const response = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(encrypted)
}).then(r => r.json());
// Decrypt response
const result = client.decryptResponse(response);
if (result.success) {
console.log('Login successful! Token:', result.token);
} else {
console.log('Login failed:', result.error);
}
}
secureLogin('admin', 'secret');Why Forward Secrecy Matters
Payload Encryptor generates new ephemeral keys for every message. This means:
- Even if a key is compromised, only that single message is at risk
- Past communications remain secure
- Each request/response pair has unique encryption keys
This is the same level of security used by Signal and WhatsApp.
Conclusion
Payload Encryptor makes it easy to add end-to-end encryption to any application. With support for all major runtimes and zero configuration required, you can secure your client-server communication in minutes.
Stop transmitting sensitive data in plain text. Start encrypting today!
npm i payload-encryptorCheck out the full documentation on npm!
