Bumps every @wrnexus package 0.8.4 -> 0.8.5 and adds the matching update migration. The migration is documentation only: moving off <Table> to <DataTable> and off the @wrnexus/ui main entry to @wrnexus/ui/registry are source changes no codemod can make safely. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@wrnexus/encryption
Authenticated encryption, hashing, HMAC, key rotation, and optional encrypted HTTP exchanges for WRNexusJS.
Core helpers
generateKey()— random 256-bit AES key encoded as base64.deriveKey(password, salt)— PBKDF2-derived AES key.encrypt(plaintext, key)/decrypt(payload, key)— AES-256-GCM.sha256(data)— SHA-256 digest.hmacSign(data, secret)/hmacVerify(...)— HMAC-SHA256.createKeyring(keys)— active/previous key management.seal()/open()— versioned ciphertext with key ID.
Encrypted HTTP envelope
import {
createEncryptedRequest,
createKeyring,
createMemoryReplayStore,
decryptEncryptedResponse,
encryptedExchange,
} from "@wrnexus/encryption";
const keyring = createKeyring([{ id: "2026-08", secret: process.env.API_BODY_KEY!, active: true }]);
const replayStore = createMemoryReplayStore();
// Server middleware.
app.use(
encryptedExchange({
keyring,
replayStore,
maxAgeMs: 60_000,
maxBodyBytes: 1_048_576,
}),
);
// Controlled service/native client.
const request = await createEncryptedRequest(
"https://api.example.com/private/report",
{ reportId: "report-1" },
{ method: "POST", keyring },
);
const response = await fetch(request);
const result = await decryptEncryptedResponse(response, request, { keyring });
The envelope binds authenticated ciphertext to:
- HTTP method
- URL path and query
- request ID
- timestamp and expiry window
- encryption key ID
- optional replay-store consumption
encryptedBody() decrypts request bodies only. encryptedExchange() also encrypts successful downstream responses while allowing application exceptions to propagate normally. encryptedFetch() provides a convenient controlled-client call.
Security boundary
Encrypted HTTP bodies do not replace TLS/HTTPS. Always use HTTPS.
This layer is appropriate for service-to-service traffic, native/mobile applications, controlled agents, and selected fields protected with server-managed keys. It cannot conceal data from an end user when browser JavaScript receives the decryption key. Never ship a long-lived server encryption key to a browser.
Use a shared replay store such as Redis in multi-instance deployments. The memory replay store is process-local.