Web Crypto API 提供一组用于常见加密任务的底层函数。Workers 运行时实现了此 API 的完整接口,但在支持的算法方面与大多数浏览器实现的算法存在差异。
使用 Web Crypto API 执行加密操作比纯 JavaScript 执行要快得多。如果您想执行 CPU 密集型的加密操作,应考虑使用 Web Crypto API。
Web Crypto API 通过 SubtleCrypto 接口实现,可通过全局 crypto.subtle 绑定(binding)访问。计算摘要(也称为哈希)的简单示例如下:
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));一些常见用途包括签名请求。
-
crypto.DigestStream(algorithm)DigestStream- 对
cryptoAPI 的非标准扩展,支持从流式数据生成哈希摘要。DigestStream本身是一个WritableStream,不会保留写入其中的数据。相反,当数据流结束时,它会自动生成哈希摘要。
- 对
-
algorithmstring | object- 以算法特定格式 ↗描述要使用的算法,包括任何必需参数。
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;-
crypto.randomUUID(): string- 生成 RFC 4122 ↗ 定义的新随机(版本 4)UUID。
-
crypto.getRandomValues(bufferArrayBufferView): ArrayBufferView- 用加密安全的随机值填充传入的
ArrayBufferView,并返回buffer。
- 用加密安全的随机值填充传入的
-
bufferArrayBufferView- 必须是 Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | BigInt64Array | BigUint64Array。
这些方法均通过 crypto.subtle ↗ 访问,MDN 上也有详细文档。
-
encrypt(algorithm, key, data): Promise<ArrayBuffer>- 返回一个 Promise,该 Promise 解析为与给定明文、算法和密钥对应的加密数据。
-
algorithmobject- 以算法特定格式 ↗描述要使用的算法,包括任何必需参数。
-
keyCryptoKey -
dataBufferSource
-
decrypt(algorithm, key, data): Promise<ArrayBuffer>- 返回一个 Promise,该 Promise 解析为与给定密文、算法和密钥对应的明文数据。
-
algorithmobject- 以算法特定格式 ↗描述要使用的算法,包括任何必需参数。
-
keyCryptoKey -
dataBufferSource
-
sign(algorithm, key, data): Promise<ArrayBuffer>- 返回一个 Promise,该 Promise 解析为与给定文本、算法和密钥对应的签名。
-
algorithmstring | object- 以算法特定格式 ↗描述要使用的算法,包括任何必需参数。
-
keyCryptoKey -
dataArrayBuffer
-
verify(algorithm, key, signature, data): Promise<boolean>- 返回一个 Promise,该 Promise 解析为布尔值,指示给定签名是否与同样给定的文本、算法和密钥匹配。
-
algorithmstring | object- 以算法特定格式 ↗描述要使用的算法,包括任何必需参数。
-
keyCryptoKey -
signatureArrayBuffer -
dataArrayBuffer
-
digest(algorithm, data): Promise<ArrayBuffer>- 返回一个 Promise,该 Promise 解析为根据给定算法和文本生成的摘要。
-
algorithmstring | object- 以算法特定格式 ↗描述要使用的算法,包括任何必需参数。
-
dataArrayBuffer
-
generateKey(algorithm, extractable, keyUsages): Promise<CryptoKey> | Promise<CryptoKeyPair>- 返回一个 Promise,该 Promise 解析为新生成的
CryptoKey(对称算法)或CryptoKeyPair(包含两个新生成密钥的非对称算法)。例如,生成新的 AES-GCM 密钥:
let keyPair = await crypto.subtle.generateKey( { name: 'AES-GCM', length: 256, }, true, ['encrypt', 'decrypt'] ); - 返回一个 Promise,该 Promise 解析为新生成的
-
algorithmobject- 以算法特定格式 ↗描述要使用的算法,包括任何必需参数。
-
extractablebool -
keyUsagesArray- 字符串数组,指示新密钥的可能用途 ↗。
-
deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages): Promise<CryptoKey>- 返回一个 Promise,该 Promise 解析为根据给定基础密钥和特定算法新生成的
CryptoKey。
- 返回一个 Promise,该 Promise 解析为根据给定基础密钥和特定算法新生成的
-
algorithmobject- 以算法特定格式 ↗描述要使用的算法,包括任何必需参数。
-
baseKeyCryptoKey -
derivedKeyAlgorithmobject- 以算法特定格式 ↗定义派生密钥将用于的算法。
-
extractablebool -
keyUsagesArray- 字符串数组,指示新密钥的可能用途 ↗。
-
deriveBits(algorithm, baseKey, length): Promise<ArrayBuffer>- 返回一个 Promise,该 Promise 解析为根据给定基础密钥和特定算法新生成的伪随机位缓冲区。它返回一个 Promise,该 Promise 解析为包含派生位的
ArrayBuffer。此方法与deriveKey()非常相似,不同之处在于deriveKey()返回CryptoKey对象而非ArrayBuffer。本质上,deriveKey()由deriveBits()后跟importKey()组成。
- 返回一个 Promise,该 Promise 解析为根据给定基础密钥和特定算法新生成的伪随机位缓冲区。它返回一个 Promise,该 Promise 解析为包含派生位的
-
algorithmobject- 以算法特定格式 ↗描述要使用的算法,包括任何必需参数。
-
baseKeyCryptoKey -
lengthint- 要派生的位串长度。
-
importKey(format, keyData, algorithm, extractable, keyUsages): Promise<CryptoKey>- 将密钥从某种外部可移植格式转换为可用于 Web Crypto API 的
CryptoKey。
- 将密钥从某种外部可移植格式转换为可用于 Web Crypto API 的
-
formatstring- 描述要导入的密钥格式 ↗。
-
keyDataArrayBuffer -
algorithmobject- 以算法特定格式 ↗描述要使用的算法,包括任何必需参数。
-
extractablebool -
keyUsagesArray- 字符串数组,指示新密钥的可能用途 ↗。
-
exportKey(formatstring, keyCryptoKey): Promise<ArrayBuffer>- 如果
CryptoKey是extractable的,则将其转换为可移植格式。
- 如果
-
formatstring- 描述密钥将被导出的格式 ↗。
-
keyCryptoKey
-
wrapKey(format, key, wrappingKey, wrapAlgo): Promise<ArrayBuffer>- 将
CryptoKey转换为可移植格式,然后用另一个密钥加密它。这使CryptoKey适合在不受信任的环境中存储或传输。
- 将
-
formatstring- 描述加密前密钥将被导出的格式 ↗。
-
keyCryptoKey -
wrappingKeyCryptoKey -
wrapAlgoobject- 以算法特定格式 ↗描述用于加密导出密钥的算法,包括任何必需参数。
-
unwrapKey(format, key, unwrappingKey, unwrapAlgo,: Promise<CryptoKey>
unwrappedKeyAlgo, extractable, keyUsages)- 将被
wrapKey()包装的密钥转换回CryptoKey。
- 将被
-
formatstring -
keyCryptoKey -
unwrappingKeyCryptoKey -
unwrapAlgoobject- 以算法特定格式 ↗描述用于加密包装密钥的算法。
-
unwrappedKeyAlgoobject- 以算法特定格式 ↗描述要解包的密钥。
-
extractablebool -
keyUsagesArray- 字符串数组,指示新密钥的可能用途 ↗。
-
timingSafeEqual(a, b): bool- 以防时序攻击的方式比较两个缓冲区。这是对 Web Crypto API 的非标准扩展。
-
aArrayBuffer | TypedArray -
bArrayBuffer | TypedArray
Workers 实现了 WebCrypto 标准 ↗ 的所有操作,如下表所示。
勾选标记 (✓) 表示此功能据信已按规范完全支持。
叉号 (✘) 表示此功能是规范的一部分但未实现。
如果功能仅部分实现操作,则列出详细信息。
| Algorithm | 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 | ✓ | ✓ |
Footnotes:
Secure Curves API ↗ 中指定的算法。
除 Secure Curves 版本外,还支持旧版非标准 EdDSA(Ed25519 曲线)。由于此算法是非标准的,使用时请注意以下事项:
- 使用
NODE-ED25519作为算法和namedCurve参数。 - 与 NodeJS 不同,Cloudflare 不支持私钥的原始导入。
- 算法实现可能会随时间变化。虽然 Cloudflare 目前无法保证,但 Cloudflare 将努力保持向后兼容以及与 NodeJS 行为的兼容性。任何重要的兼容性说明将在发布说明中传达,并通过此开发者文档提供。
- 使用
MD5 不是 WebCrypto 标准的一部分,但在 Cloudflare Workers 中受支持,用于与需要 MD5 的旧版系统交互。MD5 被认为是弱算法。不要依赖 MD5 来保证安全。