SecretKey
A data class that represents a secret key binding for Cloudflare Workers, enabling secure cryptographic operations using the Web Crypto API.
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
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
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
RSA Signing Key (JWK Format)
typescript
import { SecretKey } from "alchemy/cloudflare";
import { Worker } from "alchemy/cloudflare";
import { secret } from "alchemy";
// Generate an RSA key pair
const 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 JWK
const 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
javascript
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)
typescript
import { SecretKey } from "alchemy/cloudflare";
import { Worker } from "alchemy/cloudflare";
import { secret } from "alchemy";
// Generate a 256-bit AES key
const aesKey = await crypto.subtle.generateKey(
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"]
);
// Export as raw bytes
const 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
javascript
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
typescript
import { SecretKey } from "alchemy/cloudflare";
import { secret } from "alchemy";
// Assuming you have a PKCS#8 encoded private key
const 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
typescript
import { SecretKey } from "alchemy/cloudflare";
import { secret } from "alchemy";
// Generate HMAC key
const 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
- 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
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