# @wrnexus/encryption > Dependency-free crypto helpers for WrNexus: authenticated symmetric encryption (AES-256-GCM), hashing, and HMAC signing. Part of the **WrNexus** framework — an SSR-first, Bun-native full-stack web framework. ## Overview This package provides small, focused cryptographic primitives for server-side use: encrypting secrets/tokens/database fields at rest with AES-256-GCM, deriving keys from passwords via PBKDF2, computing SHA-256 digests, and signing/verifying payloads with HMAC-SHA256. It is built entirely on the standard **Web Crypto API** (`crypto.subtle`) plus `btoa`/`atob` and `TextEncoder`/`TextDecoder` — no third-party dependencies. Reach for it whenever you need to protect sensitive values or verify webhook signatures. All functions are `async` (Web Crypto is promise-based). ## Installation ```bash bun add @wrnexus/encryption ``` > Private package — the machine must be authenticated to the `wrnexus` npm org > (a read token in `~/.npmrc`). Requires **Bun** (Node is not supported). ## API All keys are exchanged as **base64 strings** and all digests/signatures as **hex strings**. | Export | Signature | Description | | ------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | `generateKey` | `() => Promise` | Generate a random 256-bit AES key, base64-encoded. Store it as a secret. | | `deriveKey` | `(password: string, salt: string) => Promise` | Derive a base64 AES-256 key from a password + salt using PBKDF2 (100,000 iterations, SHA-256). | | `encrypt` | `(plaintext: string, key: string) => Promise` | AES-256-GCM encrypt a string. Returns base64 of `iv(12 bytes) ‖ ciphertext+tag`. A fresh random IV is used each call. | | `decrypt` | `(payload: string, key: string) => Promise` | Decrypt a value produced by `encrypt`. Throws if the key is wrong or the data was tampered with. | | `sha256` | `(data: string) => Promise` | SHA-256 hex digest of a string (e.g. content hashing, dedup keys). | | `hmacSign` | `(data: string, secret: string) => Promise` | HMAC-SHA256 hex signature of `data` with `secret` (e.g. signing webhooks). | | `hmacVerify` | `(data: string, secret: string, signature: string) => Promise` | Constant-time verify of an HMAC-SHA256 hex signature. | Notes: - `generateKey` produces a 32-byte (256-bit) key via `crypto.getRandomValues`. - `encrypt`/`decrypt` require a base64-encoded 256-bit key; anything else throws `"Encryption key must be a base64 256-bit key"`. - `decrypt` throws `"Invalid ciphertext"` if the payload is shorter than the 12-byte IV, and the underlying Web Crypto call throws on any authentication (tag) mismatch. - `hmacVerify` compares in constant time (length check plus XOR accumulation) to avoid timing leaks. ## Usage Symmetric encryption of a secret at rest: ```ts import { generateKey, encrypt, decrypt } from "@wrnexus/encryption"; const key = await generateKey(); // store this safely (env/secret manager) const box = await encrypt("card #1234", key); // opaque base64 string, safe to persist const plain = await decrypt(box, key); // "card #1234" ``` Deriving a key from a user password instead of a random key: ```ts import { deriveKey, encrypt } from "@wrnexus/encryption"; const key = await deriveKey("correct horse battery staple", "per-user-salt"); const box = await encrypt("secret note", key); ``` Hashing and webhook signature verification: ```ts import { sha256, hmacSign, hmacVerify } from "@wrnexus/encryption"; const digest = await sha256("some content"); // 64-char hex string const signature = await hmacSign(rawBody, webhookSecret); const ok = await hmacVerify(rawBody, webhookSecret, incomingSignatureHeader); if (!ok) throw new Error("Invalid webhook signature"); ``` ## Requirements / Notes - **Bun-only.** Relies on the Web Crypto API (`crypto.subtle`, `crypto.getRandomValues`) and the global `btoa`/`atob`, `TextEncoder`/`TextDecoder` — all available in Bun's runtime. - **No dependencies.** The package has an empty dependency set; nothing is bundled beyond standard runtime APIs. - Algorithms: AES-256-GCM (encryption), PBKDF2 with 100k SHA-256 iterations (key derivation), SHA-256 (digest), HMAC-SHA256 (signing). - Keep generated/derived keys and HMAC secrets out of source control; treat them as first-class secrets.