npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

secure-encryption

v1.1.3

Published

Per-user dynamic AES-256-GCM + RSA-OAEP encryption for transport and database storage

Readme

# secure-encryption

Enterprise hybrid encryption module for **secure data transmission** and **database field storage**. Built for both **JavaScript** and **TypeScript** environments with native type definitions.

- **Transport**: Generates a fresh AES-256-GCM key for every payload (perfect forward secrecy)
- **Storage**: Per-user Data Encryption Key (DEK) protected by RSA-OAEP
- **Key Rotation**: Supports rotating keys every 24 hours without breaking active sessions
- **AAD Support**: Additional Authenticated Data binding for tamper-proof field encryption
- **Non-blocking**: Fully async RSA operations to prevent Event Loop blocking
- **Zero external dependencies** — uses only Node.js built-in `crypto`

---

## Installation

```bash
npm install secure-encryption

Features

| Feature | Description | | --- | --- | | Ephemeral AES key | New AES-256-GCM key generated for every transmission | | Per-user RSA key pair | Each user has their own RSA-3072 key pair | | Per-user DEK | Data Encryption Key for database fields, unique per user | | Key rotation | Rotate keys on login or every 24 hours | | Grace period | Previous private key kept temporarily during rotation | | Authenticated encryption | AES-GCM provides confidentiality, integrity, and optional AAD binding | | Full TypeScript Support | Bundled with high-precision .d.ts declaration files |


Simple Usage

1. Import Module

JavaScript (CommonJS):

const CybersSecure = require('secure-encryption');

TypeScript (ES Module):

import CybersSecure, { UserKeyInfo, EncryptedPayload, EncryptedField } from 'secure-encryption';

2. Create or Rotate User Keys

// First time (registration or first login)
const keyAll = await CybersSecure.rotateUserKeyPair();

// Later (on login or scheduled job)
if (CybersSecure.shouldRotateKey(user.keyAll)) {
  const newKeyAll = await CybersSecure.rotateUserKeyPair(user.keyAll);
  // Save newKeyAll to database
}

Recommended keyAll structure stored in database:

{
  provider: "CybersSecure",
  publicKey: "...",           // Can be sent to client
  privateKey: "...",          // Server-side only
  encryptedDEK: ["..."],      // DEK encrypted by RSA (Array of chunks)
  createdAt: "2026-...",
  expiresAt: "2026-...",
  previousPrivateKey: "...",  // Optional, for rotation grace period
  previousExpiresAt: "..."
}

3. Encrypt / Decrypt for API (Transport)

// Encrypt payload for recipient
const encrypted = await CybersSecure.encryptPayload({ msg: "hello" }, recipientPublicKey);
// → { provider: "CybersSecure", keys: [...], data: "..." }

// Decrypt payload
const data = await CybersSecure.decryptPayload(encrypted, privateKey);

// Recommended during key rotation window
const data = await CybersSecure.decryptPayloadWithFallback(encrypted, user.keyAll);

4. Encrypt / Decrypt Database Fields (With AAD Support)

// 1. Unwrap the user's Data Encryption Key (Async)
const dek = await CybersSecure.unwrapDataKey(user.keyAll.encryptedDEK, user.keyAll.privateKey);

// 2. Encrypt before saving to DB (Optional 3rd arg: AAD for tamper protection)
const encryptedPhone = CybersSecure.encryptField("+85298765432", dek, user.id);
// → { provider: "CybersSecure", iv: "...", ciphertext: "..." }

// 3. Decrypt after reading from DB
const phone = CybersSecure.decryptField(user.phone, dek, user.id);

Important Notes

  • Never send privateKey or raw DEK to the client.
  • Every call to encryptPayload uses a brand new AES key.
  • Each user has a different DEK for database encryption.
  • Use decryptPayloadWithFallback when keys may have been rotated.
  • Always provide contextual IDs (e.g., userId or recordId) as AAD in encryptField to prevent ciphertext relocation attacks.

API Reference

Key Management

generateRSAKeyPair()

Generates a new RSA-3072 key pair in PEM format.

Returns: Promise<{ publicKey: string, privateKey: string }>

rotateUserKeyPair(currentKeyInfo?)

Rotates the user's RSA key pair and re-wraps the DEK.

Keeps the previous private key for a 2-hour grace period.

Returns: Promise<UserKeyInfo>

shouldRotateKey(keyInfo)

Returns true if the key has expired or does not exist.

generateDataKey(userPublicKey)

Generates a random Data Encryption Key and encrypts it with the given public key.

Returns: Promise<{ encryptedDEK: string[] }>

unwrapDataKey(encryptedDEK, privateKey)

Decrypts and returns the raw DEK (Buffer).

Returns: Promise<Buffer>


Transport Encryption

encryptPayload(data, recipientPublicKey)

Hybrid encrypts a payload. Generates a new AES key every time.

Returns: Promise<EncryptedPayload>

decryptPayload(payload, privateKey)

Decrypts a hybrid-encrypted payload.

Returns: Promise<any>

decryptPayloadWithFallback(payload, keyInfo)

Tries the current private key, then falls back to previousPrivateKey if available.

Returns: Promise<any>


Database Field Encryption

encryptField(data, dek, aad?)

Encrypts a value for storage with optional AAD.

Returns: EncryptedField ({ provider, iv, ciphertext })

decryptField(stored, dek, aad?)

Decrypts a value previously encrypted with encryptField.

Returns: any


Security Notes

  • Never send or log the privateKey or raw DEK to the client.
  • Always use decryptPayloadWithFallback during the key rotation window.
  • AES-256-GCM provides authenticated encryption (detects payload tampering).
  • RSA-3072 uses OAEP with SHA-256 padding.
  • All RSA encryption and decryption operations are handled asynchronously to prevent CPU starvation on Node.js Event Loop.
  • The module uses only Node.js built-in crypto (zero external dependencies).

Requirements

  • Node.js >= 16.0.0

License

MIT