← Cloudflare Workers / workers / runtime-apis
Web Crypto
Kontext
Web Crypto API poskytuje sadu nízkoúrovňových funkcí pro běžné kryptografické úlohy. Workers runtime implementuje celý rozsah tohoto API, avšak s určitými rozdíly v podporované algoritmy ve srovnání s těmi, které jsou implementovány ve většině prohlížečů.
Kryptografické operace prováděné pomocí rozhraní Web Crypto API jsou výrazně rychlejší než jejich provádění čistě v JavaScriptu. Pokud potřebujete provádět výpočetně náročné kryptografické operace, zvažte použití rozhraní Web Crypto API.
Web Crypto API je implementované prostřednictvím SubtleCrypto rozhraní, dostupné přes globální crypto.subtle binding. Jednoduchý příklad výpočtu otisku (také nazývaného hash) vypadá takto:
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));Mezi běžná využití patří podepisování požadavků.
Konstruktory
-
crypto.DigestStream(algorithm)DigestStream- Nestandardní rozšíření
cryptoAPI, které podporuje generování hashovacího otisku ze streamovaných dat.DigestStreamsamo o sobě jeWritableStreamkterý si zapsaná data neuchovává. Místo toho po ukončení toku dat automaticky vygeneruje hash digest.
- Nestandardní rozšíření
Parametry
-
algorithmstring | object- Popisuje algoritmus, který se má použít, včetně veškerých požadovaných parametrů, v formát specifický pro daný algoritmus ↗.
Použití
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;Metody
-
crypto.randomUUID(): string- Vygeneruje nové náhodné UUID (verze 4) podle definice v RFC 4122 ↗.
-
crypto.getRandomValues(bufferArrayBufferView): ArrayBufferView- Vyplní předaný
ArrayBufferViewkryptograficky bezpečnými náhodnými hodnotami a vracíbuffer.
- Vyplní předaný
Parametry
-
bufferArrayBufferView- Musí to být Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | BigInt64Array | BigUint64Array.
Metody SubtleCrypto
Ke všem těmto metodám se přistupuje přes crypto.subtle ↗, což je rovněž podrobně zdokumentováno na MDN.
šifrovat
-
encrypt(algorithm, key, data): Promise<ArrayBuffer>- Vrátí Promise, který se splní zašifrovanými daty odpovídajícími nezašifrovanému textu, algoritmu a klíči zadaným jako parametry.
Parametry
-
algorithmobjekt- Popisuje algoritmus, který se má použít, včetně veškerých požadovaných parametrů, v formát specifický pro daný algoritmus ↗.
-
keyCryptoKey -
dataBufferSource
decrypt
-
decrypt(algorithm, key, data): Promise<ArrayBuffer>- Vrátí Promise, který se splní nezašifrovanými daty odpovídajícími šifrovanému textu, algoritmu a klíči zadaným jako parametry.
Parametry
-
algorithmobjekt- Popisuje algoritmus, který se má použít, včetně veškerých požadovaných parametrů, v formát specifický pro daný algoritmus ↗.
-
keyCryptoKey -
dataBufferSource
podepsat
-
sign(algorithm, key, data): Promise<ArrayBuffer>- Vrátí Promise, který se splní podpisem odpovídajícím textu, algoritmu a klíči zadaným jako parametry.
Parametry
-
algorithmstring | object- Popisuje algoritmus, který se má použít, včetně veškerých požadovaných parametrů, v formát specifický pro daný algoritmus ↗.
-
keyCryptoKey -
dataArrayBuffer
ověřit
-
verify(algorithm, key, signature, data): Promise<boolean>- Vrátí Promise, který se splní hodnotou typu Boolean udávající, zda podpis zadaný jako parametr odpovídá textu, algoritmu a klíči, které jsou rovněž zadány jako parametry.
Parametry
-
algorithmstring | object- Popisuje algoritmus, který se má použít, včetně veškerých požadovaných parametrů, v formát specifický pro daný algoritmus ↗.
-
keyCryptoKey -
signatureArrayBuffer -
dataArrayBuffer
digest
-
digest(algorithm, data): Promise<ArrayBuffer>- Vrátí Promise, který se splní digestem vygenerovaným z algoritmu a textu zadaných jako parametry.
Parametry
-
algorithmstring | object- Popisuje algoritmus, který se má použít, včetně veškerých požadovaných parametrů, v formát specifický pro daný algoritmus ↗.
-
dataArrayBuffer
generateKey
-
generateKey(algorithm, extractable, keyUsages): Promise<CryptoKey> | Promise<CryptoKeyPair>- Vrátí Promise, který se splní nově vygenerovaným
CryptoKey, pro symetrické algoritmy, neboCryptoKeyPair, obsahující dva nově vygenerované klíče, u asymetrických algoritmů. Nový klíč AES-GCM vygenerujete například takto:
let keyPair = await crypto.subtle.generateKey( { name: 'AES-GCM', length: 256, }, true, ['encrypt', 'decrypt'] ); - Vrátí Promise, který se splní nově vygenerovaným
Parametry
-
algorithmobjekt- Popisuje algoritmus, který se má použít, včetně veškerých požadovaných parametrů, v formát specifický pro daný algoritmus ↗.
-
extractablebool -
keyUsagesArray- Array řetězců, který určuje možné způsoby použití nového klíče ↗.
deriveKey
-
deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages): Promise<CryptoKey>- Vrátí Promise, který se splní nově vygenerovaným
CryptoKeyodvozený ze základního klíče a konkrétního algoritmu zadaného jako parametry.
- Vrátí Promise, který se splní nově vygenerovaným
Parametry
-
algorithmobjekt- Popisuje algoritmus, který se má použít, včetně veškerých požadovaných parametrů, v formát specifický pro daný algoritmus ↗.
-
baseKeyCryptoKey -
derivedKeyAlgorithmobject- Definuje algoritmus, pro který bude odvozený klíč použit v formát specifický pro daný algoritmus ↗.
-
extractablebool -
keyUsagesArray- Array řetězců, který určuje možné způsoby použití nového klíče ↗
deriveBits
-
deriveBits(algorithm, baseKey, length): Promise<ArrayBuffer>- Vrátí Promise, který se splní nově vygenerovaným bufferem pseudonáhodných bitů odvozených ze základního klíče a konkrétního algoritmu zadaných jako parametry. Vrátí Promise, který se splní
ArrayBufferobsahující odvozené bity. Tato metoda je velmi podobná metoděderiveKey(), až na to, žederiveKey()vracíCryptoKeyobjekt namístoArrayBuffer. V podstatěderiveKey()se skládá zderiveBits()a za nímimportKey().
- Vrátí Promise, který se splní nově vygenerovaným bufferem pseudonáhodných bitů odvozených ze základního klíče a konkrétního algoritmu zadaných jako parametry. Vrátí Promise, který se splní
Parametry
-
algorithmobjekt- Popisuje algoritmus, který se má použít, včetně veškerých požadovaných parametrů, v formát specifický pro daný algoritmus ↗.
-
baseKeyCryptoKey -
lengthint- Délka bitového řetězce, který se má odvodit.
importKey
-
importKey(format, keyData, algorithm, extractable, keyUsages): Promise<CryptoKey>- Transformujte klíč z nějakého externího, přenositelného formátu na
CryptoKeypro použití s Web Crypto API.
- Transformujte klíč z nějakého externího, přenositelného formátu na
Parametry
-
formatstring- Popisuje formát klíče, který se má importovat ↗.
-
keyDataArrayBuffer -
algorithmobjekt- Popisuje algoritmus, který se má použít, včetně veškerých požadovaných parametrů, v formát specifický pro daný algoritmus ↗.
-
extractablebool -
keyUsagesArray- Array řetězců, který určuje možné způsoby použití nového klíče ↗
exportKey
-
exportKey(formatstring, keyCryptoKey): Promise<ArrayBuffer>- Transformujte
CryptoKeydo přenositelného formátu, pokudCryptoKeyjeextractable.
- Transformujte
Parametry
-
formatstring- Popisuje formát, ve kterém bude klíč exportován ↗.
-
keyCryptoKey
wrapKey
-
wrapKey(format, key, wrappingKey, wrapAlgo): Promise<ArrayBuffer>- Transformujte
CryptoKeydo přenositelného formátu a poté ho zašifrujte jiným klíčem. Tím se znehodnotíCryptoKeyvhodné pro ukládání nebo přenos v nedůvěryhodných prostředích.
- Transformujte
Parametry
-
formatstring- Popisuje formát, ve kterém bude klíč exportován ↗ před zašifrováním.
-
keyCryptoKey -
wrappingKeyCryptoKey -
wrapAlgoobjekt- Popisuje algoritmus, který se má použít k zašifrování exportovaného klíče, včetně veškerých požadovaných parametrů, v formát specifický pro daný algoritmus ↗.
unwrapKey
-
unwrapKey(format, key, unwrappingKey, unwrapAlgo,: Promise<CryptoKey>
unwrappedKeyAlgo, extractable, keyUsages)- Transformujte klíč, který byl zabalen pomocí
wrapKey()zpět doCryptoKey.
- Transformujte klíč, který byl zabalen pomocí
Parametry
-
formatstring -
keyCryptoKey -
unwrappingKeyCryptoKey -
unwrapAlgoobjekt- Popisuje algoritmus použitý k zašifrování zabaleného klíče, ve formátu specifickém pro daný algoritmus ↗.
-
unwrappedKeyAlgoobjekt- Popisuje klíč, který se má rozbalit, ve formátu specifickém pro daný algoritmus ↗.
-
extractablebool -
keyUsagesArray- Array řetězců, který určuje možné způsoby použití nového klíče ↗
timingSafeEqual
-
timingSafeEqual(a, b): bool- Porovná dva buffery způsobem odolným vůči časovým útokům (timing attacks). Jde o nestandardní rozšíření Web Crypto API.
Parametry
-
aArrayBuffer | TypedArray -
bArrayBuffer | TypedArray
Podporované algoritmy
Workers implementuje všechny operace Standard WebCrypto ↗, jak ukazuje následující tabulka.
Zaškrtnutí (✓) znamená, že tato funkce je podle specifikace považována za plně podporovanou.
Znak x (✘) znamená, že tato funkce je součástí specifikace, ale není implementována.
Pokud funkce implementuje operaci pouze částečně, jsou uvedeny podrobnosti.
| Algoritmus | sign() verify() |
encrypt() decrypt() |
digest() | deriveBits() deriveKey() |
generateKey() | wrapKey() unwrapKey() |
exportKey() | importKey() |
|---|---|---|---|---|---|---|---|---|
| RSASSA PKCS1 v1.5 | ✓ | ✓ | ✓ | ✓ | ||||
| RSA PSS | ✓ | ✓ | ✓ | ✓ | ||||
| RSA OAEP | ✓ | ✓ | ✓ | ✓ | ✓ | |||
| ECDSA | ✓ | ✓ | ✓ | ✓ | ||||
| ECDH | ✓ | ✓ | ✓ | ✓ | ||||
| Ed255191 | ✓ | ✓ | ✓ | ✓ | ||||
| X255191 | ✓ | ✓ | ✓ | ✓ | ||||
| NODE ED255192 | ✓ | ✓ | ✓ | ✓ | ||||
| AES CTR | ✓ | ✓ | ✓ | ✓ | ✓ | |||
| AES CBC | ✓ | ✓ | ✓ | ✓ | ✓ | |||
| AES GCM | ✓ | ✓ | ✓ | ✓ | ✓ | |||
| AES KW | ✓ | ✓ | ✓ | ✓ | ||||
| HMAC | ✓ | ✓ | ✓ | ✓ | ||||
| SHA 1 | ✓ | |||||||
| SHA 256 | ✓ | |||||||
| SHA 384 | ✓ | |||||||
| SHA 512 | ✓ | |||||||
| MD53 | ✓ | |||||||
| HKDF | ✓ | ✓ | ||||||
| PBKDF2 | ✓ | ✓ |
Poznámky pod čarou:
-
algoritmy podle specifikace v Secure Curves API ↗.
-
Vedle verze Secure Curves je podporována i zastaralá nestandardní varianta EdDSA pro křivku Ed25519. Vzhledem k tomu, že tento algoritmus není standardní, mějte při jeho používání na paměti následující:
- Použijte
NODE-ED25519jako algoritmus anamedCurveparametry. - Na rozdíl od NodeJS nebude Cloudflare podporovat přímý import privátních klíčů.
- Implementace algoritmu se může časem měnit. Cloudflare to v tuto chvíli nemůže zaručit, bude se však snažit zachovat zpětnou kompatibilitu i soulad s chováním NodeJS. Veškeré významné poznámky ke kompatibilitě budou uvedeny v poznámkách k vydání a v této dokumentaci pro vývojáře.
- Použijte
-
MD5 není součástí standardu WebCrypto, ale je v Cloudflare Workers podporován pro komunikaci se staršími systémy, které MD5 vyžadují. MD5 je považován za slabý algoritmus. Nespoléhejte se na MD5 z hlediska zabezpečení.