Feature Request
Summary
The current cookie helper only supports signed cookies (HMAC-SHA256), which provides integrity but not confidentiality — the cookie value remains readable in plaintext.
This request adds encrypted cookie support using AES-256-GCM via the Web Crypto API, providing both confidentiality and integrity for cookie values.
Motivation
- Signed cookies (
setSignedCookie) prove the value wasn't tampered with, but the value is still visible (e.g., session=user-id-123.signature).
- Encrypted cookies make the value opaque — useful for storing sensitive data like session tokens, user preferences, or any data that should not be readable client-side.
- AES-256-GCM is the standard choice: authenticated encryption with a single pass.
Proposed API
Mirror the existing signed cookie API:
import {
setEncryptedCookie,
getEncryptedCookie,
generateEncryptedCookie,
} from 'hono/cookie'
// Set
await setEncryptedCookie(c, 'session', 'sensitive-data', secret)
// Get (returns string | undefined | false)
const value = await getEncryptedCookie(c, secret, 'session')
// Generate without setting on response
const cookie = await generateEncryptedCookie('session', 'sensitive-data', secret)
Design
- Algorithm: AES-256-GCM via
crypto.subtle (multi-runtime: Node, Deno, Bun, CF Workers)
- Key derivation: HKDF-SHA256 from
string | BufferSource secret (same type as signed cookies)
- IV: Random 12 bytes per encryption via
crypto.getRandomValues()
- AAD: Cookie name bound as additional authenticated data (prevents copying encrypted values between cookie names)
- Cookie format:
base64(iv || ciphertext || authTag), URL-encoded
- Prefix support: Full
__Secure- / __Host- prefix support
- Return semantics:
false on decryption failure (tampered/wrong key), same as getSignedCookie
Checklist
Feature Request
Summary
The current cookie helper only supports signed cookies (HMAC-SHA256), which provides integrity but not confidentiality — the cookie value remains readable in plaintext.
This request adds encrypted cookie support using AES-256-GCM via the Web Crypto API, providing both confidentiality and integrity for cookie values.
Motivation
setSignedCookie) prove the value wasn't tampered with, but the value is still visible (e.g.,session=user-id-123.signature).Proposed API
Mirror the existing signed cookie API:
Design
crypto.subtle(multi-runtime: Node, Deno, Bun, CF Workers)string | BufferSourcesecret (same type as signed cookies)crypto.getRandomValues()base64(iv || ciphertext || authTag), URL-encoded__Secure-/__Host-prefix supportfalseon decryption failure (tampered/wrong key), same asgetSignedCookieChecklist
secure,host)