Encryption

Encrypt values at rest with Node.js crypto or the Web Crypto API.

Encryption runs last on write (after serialize and optional compress) and first on read. It requires a serializer — the built-in JSON serializer is enough. With serialization: false, writes fail with an error instead of storing values unencrypted.

import Keyv from "keyv";
import KeyvEncryptNode from "@keyv/encrypt-node";

const keyv = new Keyv({
	encryption: new KeyvEncryptNode({ key: process.env.KEYV_SECRET }),
});

await keyv.set("secret", { token: "…" });
await keyv.get("secret"); // decrypted automatically

Use a random secret as the key, such as the output of openssl rand -base64 32, kept out of source control. Both adapters hash a string key once with SHA-256, with no salt or key stretching, so a password or passphrase can be guessed offline from a single stored value. You can also pass the raw key bytes (Buffer or Uint8Array) at the algorithm's key length. If the key has to come from a password or passphrase, derive those bytes with PBKDF2 first: the encrypt-node and encrypt-web pages show how.

Table of Contents

Official adapters

Package Runtime Default cipher
@keyv/encrypt-node Node.js crypto AES-256-GCM (AES-CCM, ChaCha20-Poly1305)
@keyv/encrypt-web Web Crypto (crypto.subtle) AES-256-GCM (AES-128-GCM, AES-192-GCM)

Use encrypt-web in browsers, Deno, and Cloudflare Workers. Use encrypt-node when you want Node-only ciphers.

Custom adapter

interface KeyvEncryptionAdapter {
	encrypt: (data: string) => string | Promise<string>;
	decrypt: (data: string) => string | Promise<string>;
}
const encryption = {
	encrypt: async (data) => Buffer.from(data).toString("base64"),
	decrypt: async (data) => Buffer.from(data, "base64").toString("utf8"),
};
const keyv = new Keyv({ encryption });

Detect adapters with detectKeyvEncryption. See Encode and Decode and Detect Capabilities.

Edit this page