@powerforgeai/aes-256-gcm
v0.1.0
Published
Production-grade AES-256-GCM authenticated encryption for Node.js. Envelope format ([IV]:[AuthTag]:[Ciphertext]), startup key validation, zero runtime dependencies.
Maintainers
Readme
@powerforgeai/aes-256-gcm
Production-grade AES-256-GCM authenticated encryption for Node.js. Single-string envelope format, fail-fast startup validation, zero runtime dependencies.
Installation
npm install @powerforgeai/aes-256-gcmQuick start
import { encrypt, decrypt } from "@powerforgeai/aes-256-gcm";
const envelope = encrypt("hello, world"); // store this anywhere — DB column, log, JSON field
const original = decrypt(envelope); // → "hello, world"Set ENCRYPTION_KEY in your environment to a 64-character hex string:
ENCRYPTION_KEY=$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))")API
encrypt(plaintext: string): string
Encrypts a UTF-8 string using the key from ENCRYPTION_KEY. Returns a base64 envelope of the form IV:AuthTag:Ciphertext. Each call produces a fresh IV, so identical plaintexts encrypt to different envelopes.
decrypt(envelope: string): string
Inverse of encrypt. Throws on tampered ciphertext, invalid envelope shape, or missing/invalid ENCRYPTION_KEY.
encryptText / decryptText
Identity-equal aliases of encrypt / decrypt. Provided so codebases that already name their helpers encryptText / decryptText can adopt this library without renaming call sites.
validateEnv(): void
Eagerly read and validate ENCRYPTION_KEY. Call this once at application startup to fail fast on misconfiguration, instead of at the first encryption call. The validated key is cached for the process lifetime.
// app entrypoint
import { validateEnv } from "@powerforgeai/aes-256-gcm";
validateEnv();createCipher(key: string | Buffer): Cipher
Creates an encryption/decryption pair bound to an explicit key. Use this for per-tenant key derivation, KMS rotation, test fixtures, or anywhere a single environment variable is the wrong model.
key— a 64-character hex string (lower- or uppercase) or a 32-byteBuffer.- Returns
{ encrypt(plaintext: string): string; decrypt(envelope: string): string }. - The key never leaves the returned closure.
import { createCipher } from "@powerforgeai/aes-256-gcm";
const tenantCipher = createCipher(deriveTenantKey(tenantId));
const envelope = tenantCipher.encrypt("tenant payload");
const plaintext = tenantCipher.decrypt(envelope);Cipher
TypeScript interface describing the value returned by createCipher.
Security notes
Envelope format
base64(IV) ":" base64(AuthTag) ":" base64(Ciphertext)- IV: 12 bytes (96 bits) — the size recommended by NIST SP 800-38D for GCM
- AuthTag: 16 bytes (128 bits)
- Ciphertext: variable length
Each component is base64-encoded so the envelope is a single colon-separated ASCII string — safe to store in a database column, log line, JSON field, URL parameter, or message queue.
Key requirements
- 32 bytes (256 bits) of cryptographically random data
- Provided as a 64-character hex string or a 32-byte
Buffer - Never reuse a key across unrelated systems
- Never commit a key to source control — use environment variables, a secrets manager, or a KMS
Generate a key:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Startup validation
encrypt and decrypt validate ENCRYPTION_KEY lazily — on the first call, not at module load. To surface misconfiguration at boot time (recommended for servers, workers, and CI), call validateEnv() from your application entrypoint. The validated key is cached for the process lifetime; subsequent mutations of process.env.ENCRYPTION_KEY are ignored.
Integrity guarantees
GCM is authenticated encryption. Any modification to the IV, auth tag, or ciphertext after encryption causes decrypt to throw. There is no silent fallback and no plaintext-on-failure mode. A wrong key produces the same throw — you cannot tell from the error whether the envelope was tampered with or simply decrypted with the wrong key, by design.
Out of scope
- Key rotation. Bring your own strategy. For rotating or tenant-scoped keys, derive externally and pass to
createCipher. - Key derivation. This library does not run PBKDF2 / scrypt / argon2. Provide a random 32-byte key.
- Streaming. This library encrypts complete strings, not streams.
- Binary input. Only UTF-8 strings. Base64-encode binary data first if needed.
Why this library
Most npm AES libraries either expose crypto raw — leaving you to reimplement IV handling, base64 plumbing, and key validation in every project — or wrap it in a configuration object that obscures the algorithm. This library does one thing: AES-256-GCM, single-string envelope, explicit key contract. No init(), no async, no provider plugins, no transitive dependencies.
License
MIT — see LICENSE.
