SecretKey
A data class that represents a secret key binding for Cloudflare Workers, enabling secure cryptographic operations using the Web Crypto API.
Overview
Section titled “Overview”The SecretKey
binding allows you to securely store and use cryptographic keys in your Cloudflare Workers. Keys are stored as bindings and exposed as CryptoKey
objects that can be used with the SubtleCrypto API.
Key Formats
Section titled “Key Formats”SecretKey supports multiple key formats:
raw
- Raw binary key datapkcs8
- PKCS #8 format for private keysspki
- SubjectPublicKeyInfo format for public keysjwk
- JSON Web Key format
Key Usages
Section titled “Key Usages”Keys can be configured with specific usage permissions:
encrypt
/decrypt
- For encryption/decryption operationssign
/verify
- For digital signaturesderiveKey
/deriveBits
- For key derivationwrapKey
/unwrapKey
- For key wrapping
Examples
Section titled “Examples”RSA Signing Key (JWK Format)
Section titled “RSA Signing Key (JWK Format)”import { SecretKey } from "alchemy/cloudflare";import { Worker } from "alchemy/cloudflare";import { secret } from "alchemy";
// Generate an RSA key pairconst keyPair = await crypto.subtle.generateKey( { name: "RSA-PSS", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256", }, true, // extractable ["sign", "verify"]);
// Export the private key as JWKconst privateKeyJwk = await crypto.subtle.exportKey("jwk", keyPair.privateKey);
const signingKey = new SecretKey({ algorithm: { name: "RSA-PSS", hash: "SHA-256" }, format: "jwk", usages: ["sign"], key_jwk: secret(privateKeyJwk),});
const worker = await Worker("my-worker", { entrypoint: "./worker.ts", bindings: { SIGNING_KEY: signingKey, },});
worker.ts
export default { async fetch(request, env) { const data = new TextEncoder().encode("Hello, World!");
const signature = await crypto.subtle.sign( { name: "RSA-PSS", saltLength: 32 }, env.SIGNING_KEY, data );
return Response.json({ signed: Array.from(new Uint8Array(signature)), }); },};
AES Encryption Key (Raw Format)
Section titled “AES Encryption Key (Raw Format)”import { SecretKey } from "alchemy/cloudflare";import { Worker } from "alchemy/cloudflare";import { secret } from "alchemy";
// Generate a 256-bit AES keyconst aesKey = await crypto.subtle.generateKey( { name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"]);
// Export as raw bytesconst keyData = await crypto.subtle.exportKey("raw", aesKey);const keyBase64 = btoa(String.fromCharCode(...new Uint8Array(keyData)));
const encryptionKey = new SecretKey({ algorithm: { name: "AES-GCM" }, format: "raw", usages: ["encrypt", "decrypt"], key_base64: secret(keyBase64),});
const worker = await Worker("encryption-worker", { bindings: { ENCRYPTION_KEY: encryptionKey, }, entrypoint: "./encryption-worker.js",});
encryption-worker.js
export default { async fetch(request, env) { const plaintext = new TextEncoder().encode("secret message"); const iv = crypto.getRandomValues(new Uint8Array(12));
const ciphertext = await crypto.subtle.encrypt( { name: "AES-GCM", iv }, env.ENCRYPTION_KEY, plaintext );
return Response.json({ ciphertext: Array.from(new Uint8Array(ciphertext)), iv: Array.from(iv), }); },};
ECDSA Key from PKCS#8
Section titled “ECDSA Key from PKCS#8”import { SecretKey } from "alchemy/cloudflare";import { secret } from "alchemy";
// Assuming you have a PKCS#8 encoded private keyconst pkcs8Key = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg...";
const ecdsaKey = new SecretKey({ algorithm: { name: "ECDSA", namedCurve: "P-256" }, format: "pkcs8", usages: ["sign"], key_base64: secret(pkcs8Key),});
HMAC Key for Message Authentication
Section titled “HMAC Key for Message Authentication”import { SecretKey } from "alchemy/cloudflare";import { secret } from "alchemy";
// Generate HMAC keyconst hmacKey = await crypto.subtle.generateKey( { name: "HMAC", hash: "SHA-256" }, true, ["sign", "verify"]);
const keyData = await crypto.subtle.exportKey("raw", hmacKey);const keyBase64 = btoa(String.fromCharCode(...new Uint8Array(keyData)));
const macKey = new SecretKey({ algorithm: { name: "HMAC", hash: "SHA-256" }, format: "raw", usages: ["sign", "verify"], key_base64: secret(keyBase64),});
Security Considerations
Section titled “Security Considerations”- Key Storage: Keys are securely stored by Cloudflare and never exposed in plain text
- Access Control: Keys are only accessible to the specific Worker they’re bound to
- Usage Restrictions: The
usages
array strictly controls what operations can be performed - Non-extractable: Keys imported into Workers are typically non-extractable for security
Algorithm Support
Section titled “Algorithm Support”SecretKey works with all algorithms supported by the Web Crypto API:
- RSA (RSA-OAEP, RSA-PSS, RSASSA-PKCS1-v1_5)
- ECDSA / ECDH (P-256, P-384, P-521)
- AES (AES-CBC, AES-CTR, AES-GCM, AES-KW)
- HMAC (SHA-1, SHA-256, SHA-384, SHA-512)
- PBKDF2, HKDF
- Ed25519, X25519