Web Crypto
Last updated Sep 30, 2026
Background
The Web Crypto API provides a set of low-level functions for common cryptographic tasks. The Workers runtime implements the full surface of this API, but with some differences in the supported algorithms compared to those implemented in most browsers.
Performing cryptographic operations using the Web Crypto API is significantly faster than performing them purely in JavaScript. If you want to perform CPU-intensive cryptographic operations, you should consider using the Web Crypto API.
The Web Crypto API is implemented through the SubtleCrypto interface, accessible via the global crypto.subtle binding. A simple example of calculating a digest (also known as a hash) is:
const myText = new TextEncoder().encode('Hello world!');
const myDigest = await crypto.subtle.digest(
{
name: 'SHA-256',
},
myText // The data you want to hash as an ArrayBuffer
);
console.log(new Uint8Array(myDigest));
Some common uses include signing requests.
Caution
The Web Crypto API differs significantly from the Node.js Crypto API. If you are working with code that relies on the Node.js Crypto API, you can use it by enabling the nodejs_compat compatibility flag.
Constructors
crypto.DigestStream(algorithm)DigestStream- A non-standard extension to the
cryptoAPI that supports generating a hash digest from streaming data. TheDigestStreamitself is aWritableStreamthat does not retain the data written into it. Instead, it generates a hash digest automatically when the flow of data has ended.
Parameters
algorithmstring | object- Describes the algorithm to be used, including any required parameters, in an algorithm-specific format ↗︎.
Usage
export default {
async fetch(req) {
// Fetch from origin
const res = await fetch(req);
// We need to read the body twice so we `tee` it (get two instances)
const [bodyOne, bodyTwo] = res.body.tee();
// Make a new response so we can set the headers (responses from `fetch` are immutable)
const newRes = new Response(bodyOne, res);
// Create a SHA-256 digest stream and pipe the body into it
const digestStream = new crypto.DigestStream("SHA-256");
bodyTwo.pipeTo(digestStream);
// Get the final result
const digest = await digestStream.digest;
// Turn it into a hex string
const hexString = [...new Uint8Array(digest)]
.map(b => b.toString(16).padStart(2, '0'))
.join('')
// Set a header with the SHA-256 hash and return the response
newRes.headers.set("x-content-digest", `SHA-256=${hexString}`);
return newRes;
}
}
export default {
async fetch(req): Promise<Response> {
// Fetch from origin
const res = await fetch(req);
// We need to read the body twice so we `tee` it (get two instances)
const [bodyOne, bodyTwo] = res.body.tee();
// Make a new response so we can set the headers (responses from `fetch` are immutable)
const newRes = new Response(bodyOne, res);
// Create a SHA-256 digest stream and pipe the body into it
const digestStream = new crypto.DigestStream("SHA-256");
bodyTwo.pipeTo(digestStream);
// Get the final result
const digest = await digestStream.digest;
// Turn it into a hex string
const hexString = [...new Uint8Array(digest)]
.map(b => b.toString(16).padStart(2, '0'))
.join('')
// Set a header with the SHA-256 hash and return the response
newRes.headers.set("x-content-digest", `SHA-256=${hexString}`);
return newRes;
}
} satisfies ExportedHandler;
Methods
crypto.randomUUID(): string- Generates a new random (version 4) UUID as defined in RFC 4122 ↗︎.
crypto.getRandomValues(bufferArrayBufferView): ArrayBufferView- Fills the passed
ArrayBufferViewwith cryptographically sound random values and returns thebuffer.
Parameters
bufferArrayBufferView- Must be an Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | BigInt64Array | BigUint64Array.
SubtleCrypto Methods
These methods are all accessed via crypto.subtle ↗︎, which is also documented in detail on MDN.
encrypt
encrypt(algorithm, key, data): Promise\<ArrayBuffer>- Returns a Promise that fulfills with the encrypted data corresponding to the clear text, algorithm, and key given as parameters.
Parameters
algorithmobject- Describes the algorithm to be used, including any required parameters, in an algorithm-specific format ↗︎.
keyCryptoKeydataBufferSource
decrypt
decrypt(algorithm, key, data): Promise\<ArrayBuffer>- Returns a Promise that fulfills with the clear data corresponding to the ciphertext, algorithm, and key given as parameters.
Parameters
algorithmobject- Describes the algorithm to be used, including any required parameters, in an algorithm-specific format ↗︎.
keyCryptoKeydataBufferSource
sign
sign(algorithm, key, data): Promise\<ArrayBuffer>- Returns a Promise that fulfills with the signature corresponding to the text, algorithm, and key given as parameters.
Parameters
algorithmstring | object- Describes the algorithm to be used, including any required parameters, in an algorithm-specific format ↗︎.
keyCryptoKeydataArrayBuffer
verify
verify(algorithm, key, signature, data): Promise\<boolean>- Returns a Promise that fulfills with a Boolean value indicating if the signature given as a parameter matches the text, algorithm, and key that are also given as parameters.
Parameters
algorithmstring | object- Describes the algorithm to be used, including any required parameters, in an algorithm-specific format ↗︎.
keyCryptoKeysignatureArrayBufferdataArrayBuffer
digest
digest(algorithm, data): Promise\<ArrayBuffer>- Returns a Promise that fulfills with a digest generated from the algorithm and text given as parameters.
Parameters
algorithmstring | object- Describes the algorithm to be used, including any required parameters, in an algorithm-specific format ↗︎.
dataArrayBuffer
generateKey
generateKey(algorithm, extractable, keyUsages): Promise\<CryptoKey> | Promise\<CryptoKeyPair>- Returns a Promise that fulfills with a newly-generated
CryptoKey, for symmetrical algorithms, or aCryptoKeyPair, containing two newly generated keys, for asymmetrical algorithms. For example, to generate a new AES-GCM key:
js
let keyPair = await crypto.subtle.generateKey(
{
name: 'AES-GCM',
length: 256,
},
true,
['encrypt', 'decrypt']
);
Parameters
algorithmobject- Describes the algorithm to be used, including any required parameters, in an algorithm-specific format ↗︎.
extractableboolkeyUsagesArray- An Array of strings indicating the possible usages of the new key ↗︎.
deriveKey
deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages): Promise\<CryptoKey>- Returns a Promise that fulfills with a newly generated
CryptoKeyderived from the base key and specific algorithm given as parameters.
Parameters
algorithmobject- Describes the algorithm to be used, including any required parameters, in an algorithm-specific format ↗︎.
baseKeyCryptoKeyderivedKeyAlgorithmobject- Defines the algorithm the derived key will be used for in an algorithm-specific format ↗︎.
extractableboolkeyUsagesArray- An Array of strings indicating the possible usages of the new key ↗︎
deriveBits
deriveBits(algorithm, baseKey, length): Promise\<ArrayBuffer>- Returns a Promise that fulfills with a newly generated buffer of pseudo-random bits derived from the base key and specific algorithm given as parameters. It returns a Promise which will be fulfilled with an
ArrayBuffercontaining the derived bits. This method is very similar toderiveKey(), except thatderiveKey()returns aCryptoKeyobject rather than anArrayBuffer. Essentially,deriveKey()is composed ofderiveBits()followed byimportKey().
