Web Crypto

更新时间:2024-08-14 19:50:33

Web Crypto API 多用于常见的加密任务,基于 Web 标准的 Web Crypto API 设计。Edge Cloud Apps 函数运行时实现了此 API 的完整功能。相比纯 JavaScript 实现的加密接口,Web Crypto API 的性能更高。如果您需要执行 CPU 密集型加密操作,则应考虑使用 Web Crypto API。

注意: 出于安全考虑,Web Crypto API 只能在 HTTPS 环境下使用。

描述

Web Crypto API 通过 SubtleCrypto 接口实现,可通过全局 crypto.subtle 绑定访问。以下是一个计算摘要(也称为哈希)的简单示例:

// 编码
const myText = new TextEncoder().encode('Hello world!');

// 使用 crypto 生成 SHA-256 哈希值 Promise<ArrayBuffer>
const myDigest = await crypto.subtle.digest(
  {
    name: 'SHA-256',
  },
  myText // 要进行哈希处理的数据,以 ArrayBuffer 形式提供
);

console.log(new Uint8Array(myDigest));

一些常见用途包括对请求进行签名。

方法

crypto.randomUUID()

crypto.randomUUID(): string

返回值: 返回一个新的随机(版本 4)UUID,如 RFC 4122 中所定义。

描述: 生成一个新的随机(版本 4)UUID。

crypto.getRandomValues()

crypto.getRandomValues(buffer: ArrayBufferView): ArrayBufferView

参数:

  • buffer: 必须是 Int8ArrayUint8ArrayUint8ClampedArrayInt16ArrayUint16ArrayInt32ArrayUint32ArrayBigInt64ArrayBigUint64Array

返回值: 返回传入的 ArrayBufferView,填充了加密安全的随机值。

描述: 使用加密安全的随机值填充传入的 ArrayBufferView 并返回该缓冲区。

SubtleCrypto 方法

这些方法都通过 crypto.subtle 访问,MDN 上也有详细记录。

encrypt()

crypto.subtle.encrypt(algorithm: object, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer>

参数:

  • algorithm: 一个对象,以特定于算法的格式描述要使用的算法,包括任何必需的参数。
  • key: CryptoKey 类型,表示加密数据的密钥。
  • data: BufferSource 类型,表示要加密的数据。

返回值: 返回一个 Promise,其中包含与明文、算法和作为参数提供的密钥相对应的加密数据。

描述: 返回一个 Promise,其中包含与明文、算法和作为参数提供的密钥相对应的加密数据。

decrypt()

crypto.subtle.decrypt(algorithm: object, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer> 

参数:

  • algorithm: 一个对象,以特定于算法的格式描述要使用的算法,包括任何必需的参数。
  • key: CryptoKey 类型,表示解密数据的密钥。
  • data: BufferSource 类型,表示要解密的数据。

返回值: 返回一个 Promise,其中包含与密文、算法和作为参数提供的密钥相对应的明文数据。

描述: 返回一个 Promise,其中包含与密文、算法和作为参数提供的密钥相对应的明文数据。

sign()

crypto.subtle.sign(algorithm: string | object, key: CryptoKey, data: ArrayBuffer): Promise<ArrayBuffer> 

参数:

  • algorithm: 一个字符串或对象,以特定于算法的格式描述要使用的算法,包括任何必需的参数。
  • key: CryptoKey 类型,表示用于签名的密钥。
  • data: ArrayBuffer 类型,表示要签名的数据。

返回值: 返回一个 Promise,其中包含与文本、算法和作为参数提供的密钥相对应的签名。

描述: 返回一个 Promise,其中包含与文本、算法和作为参数提供的密钥相对应的签名。

verify()

crypto.subtle.verify(algorithm: string | object, key: CryptoKey, signature: ArrayBuffer, data: ArrayBuffer): Promise<boolean> 

参数:

  • algorithm: 一个字符串或对象,以特定于算法的格式描述要使用的算法,包括任何必需的参数。
  • key: CryptoKey 类型,表示用于验证签名的密钥。
  • signature: ArrayBuffer 类型,表示要验证的签名。
  • data: ArrayBuffer 类型,表示要验证的数据。

返回值: 返回一个 Promise,其中包含一个布尔值,指示作为参数给出的签名是否与同样作为参数给出的文本、算法和密钥匹配。

描述: 返回一个 Promise,其中包含一个布尔值,指示作为参数给出的签名是否与同样作为参数给出的文本、算法和密钥匹配。

digest()

crypto.subtle.digest(algorithm: string | object, data: ArrayBuffer): Promise<ArrayBuffer>

参数:

  • algorithm: 一个字符串或对象,以特定于算法的格式描述要使用的算法,包括任何必需的参数。
  • data: ArrayBuffer 类型,表示要计算摘要的数据。

返回值: 返回一个 Promise,其中包含从算法和作为参数提供的文本生成的摘要。

描述: 返回一个 Promise,其中包含从算法和作为参数提供的文本生成的摘要。

generateKey()

crypto.subtle.generateKey(algorithm: object, extractable: boolean, keyUsages: Array<string>): Promise<CryptoKey> | Promise<CryptoKeyPair>

参数:

  • algorithm: 一个对象,以特定于算法的格式描述要使用的算法,包括任何必需的参数。
  • extractable: 布尔值,指示生成的密钥是否可导出。
  • keyUsages: 一个字符串数组,指示新密钥的可能用途。

返回值: 返回一个 Promise,该 Promise 对于对称算法使用新生成的 CryptoKey 完成,或者对于非对称算法,使用包含两个新生成密钥的 CryptoKeyPair 完成。例如,要生成新的 AES-GCM 密钥:

let keyPair = await crypto.subtle.generateKey(
  {
    name: 'AES-GCM',
    length: 256,
  },
  true,
  ['encrypt', 'decrypt']
);

描述: 返回一个 Promise,该 Promise 使用新生成的 CryptoKey 完成,用于对称算法,或者使用包含两个新生成密钥的 CryptoKeyPair 完成,用于非对称算法。

deriveKey()

crypto.subtle.deriveKey(algorithm: object, baseKey: CryptoKey, derivedKeyAlgorithm: object, extractable: boolean, keyUsages: Array<string>): Promise<CryptoKey> 

参数:

  • algorithm: 一个对象,以特定于算法的格式描述要使用的算法,包括任何必需的参数。
  • baseKey: CryptoKey 类型,表示用于派生新密钥的基础密钥。
  • derivedKeyAlgorithm: 一个对象,以特定于算法的格式定义派生密钥将用于的算法。
  • extractable: 布尔值,表示派生密钥是否可导出。
  • keyUsages: 一个字符串数组,指示新密钥的可能用途。

返回值: 返回一个 Promise,其中包含从作为参数提供的基本密钥和特定算法派生的新生成的 CryptoKey

描述: 返回一个 Promise,其中包含从作为参数提供的基本密钥和特定算法派生的新生成的 CryptoKey

deriveBits()

crypto.subtle.deriveBits(algorithm: object, baseKey: CryptoKey, length: number): Promise<ArrayBuffer> 

参数:

  • algorithm: 一个对象,以特定于算法的格式描述要使用的算法,包括任何必需的参数。
  • baseKey: CryptoKey 类型,表示用于派生位的基密钥。
  • length: 要派生的位字符串的长度。

返回值: 返回一个 Promise,其中包含从作为参数提供的基本密钥和特定算法派生的新生成的伪随机位缓冲区。 它返回一个 Promise,该 Promise 将使用包含派生位的 ArrayBuffer 完成。 此方法与 deriveKey() 非常相似,只是 deriveKey() 返回一个 CryptoKey 对象而不是一个 ArrayBuffer。 从本质上讲,deriveKey()deriveBits() 后跟 importKey() 组成。

描述: 返回一个 Promise,其中包含从作为参数提供的基本密钥和特定算法派生的新生成的伪随机位缓冲区。

importKey()

crypto.subtle.importKey(format: string, keyData: ArrayBuffer, algorithm: object, extractable: boolean, keyUsages: Array<string>): Promise<CryptoKey> 

参数:

  • format: 一个字符串,描述要导入的密钥的格式。
  • keyData: ArrayBuffer 类型,表示要导入的密钥数据。
  • algorithm: 一个对象,以特定于算法的格式描述要使用的算法,包括任何必需的参数。
  • extractable: 布尔值,表示导入的密钥是否可导出。
  • keyUsages: 一个字符串数组,指示新密钥的可能用途。

返回值: 返回一个 Promise,该 Promise 将使用从某些外部可移植格式转换而来的密钥完成,以供 Web Crypto API 使用。

描述: 将密钥从某些外部可移植格式转换为 CryptoKey,以供 Web Crypto API 使用。

exportKey()

crypto.subtle.exportKey(format: string, key: CryptoKey): Promise<ArrayBuffer>

参数:

  • format: 一个字符串,描述密钥将被导出的格式。
  • key: CryptoKey 类型,表示要导出的密钥。

返回值: 返回一个 Promise,如果 CryptoKey 可导出,则该 Promise 将使用可移植格式的密钥完成。

描述:CryptoKey 转换为可移植格式,如果 CryptoKey 可导出。

wrapKey()

crypto.subtle.wrapKey(format: string, key: CryptoKey, wrappingKey: CryptoKey, wrapAlgo: object): Promise<ArrayBuffer> 

参数:

  • format: 一个字符串,描述密钥在被加密之前将被导出的格式。
  • key: CryptoKey 类型,表示要导出的密钥。
  • wrappingKey: CryptoKey 类型,表示将用于加密导出密钥的密钥。
  • wrapAlgo: 一个对象,以特定于算法的格式描述将用于加密导出密钥的算法,包括任何必需的参数。

返回值: 返回一个 Promise,该 Promise 将使用可移植格式的密钥完成,然后使用另一个密钥对其进行加密。 这使得 CryptoKey 适用于在不受信任的环境中进行存储或传输。

描述:CryptoKey 转换为可移植格式,然后使用另一个密钥对其进行加密。

unwrapKey()

crypto.subtle.unwrapKey(format: string, key: CryptoKey, unwrappingKey: CryptoKey, unwrapAlgo: object, 
unwrappedKeyAlgo: object, extractable: boolean, keyUsages: Array<string>): Promise<CryptoKey> 

参数:

  • format: 一个字符串,描述要解包的密钥的数据格式。
  • key: CryptoKey 类型,表示要解包的密钥。
  • unwrappingKey: CryptoKey 类型,表示将用于解包密钥的密钥。
  • unwrapAlgo: 一个对象,以特定于算法的格式描述用于加密包装密钥的算法。
  • unwrappedKeyAlgo: 一个对象,以特定于算法的格式描述要解包的密钥。
  • extractable: 布尔值,表示解包的密钥是否可导出。
  • keyUsages: 一个字符串数组,指示新密钥的可能用途。

返回值: 返回一个 Promise,该 Promise 将使用由 wrapKey() 包装的密钥转换回 CryptoKey 完成。

描述: 将由 wrapKey() 包装的密钥转换回 CryptoKey

timingSafeEqual()

crypto.subtle.timingSafeEqual(a: ArrayBuffer | TypedArray, b: ArrayBuffer | TypedArray): boolean

参数:

  • a: ArrayBufferTypedArray 类型,表示要比较的第一个缓冲区。
  • b: ArrayBufferTypedArray 类型,表示要比较的第二个缓冲区。

返回值: 返回一个布尔值,指示两个缓冲区是否相等。

描述: 以一种能够抵抗计时攻击的方式比较两个缓冲区。这是 Web Crypto API 的非标准扩展。

构造函数

crypto.DigestStream(algorithm)

返回值: DigestStream 对象

描述: Web Crypto API 的非标准扩展,支持从流数据生成哈希摘要。DigestStream 本身是一个 WritableStream,它不保留写入其中的数据。 相反,当数据流结束时,它会自动生成哈希摘要。

参数:

  • algorithm: 一个字符串或对象,以特定于算法的格式描述要使用的算法,包括任何必需的参数。

用法:

export default {
  async fetch(req) {
    // 从源获取数据
    const res = await fetch(req);

    // 我们需要读取两次 body,所以我们对其进行 `tee` 操作(获取两个实例)
    const [bodyOne, bodyTwo] = res.body.tee();
    // 创建一个新的响应,以便我们可以设置标头(来自 `fetch` 的响应是不可变的)
    const newRes = new Response(bodyOne, res);
    // 创建一个 SHA-256 摘要流并将 body  管道传输到其中
    const digestStream = new crypto.DigestStream("SHA-256");
    bodyTwo.pipeTo(digestStream);
    // 获取最终结果
    const digest = await digestStream.digest;
    // 将其转换为十六进制字符串
    const hexString = [...new Uint8Array(digest)]
      .map(b => b.toString(16).padStart(2, '0'))
      .join('')
    // 使用 SHA-256 哈希设置标头并返回响应
    newRes.headers.set("x-content-digest", `SHA-256=${hexString}`);
    return newRes;
  }
}

支持的算法

Edge Cloud Apps 函数支持 Web APIs 标准 Web Crypto 定义的部分算法,详细如下表所示。

Algorithm encrypt() decrypt() sign() verify() wrapKey() unwrapKey() deriveKey() deriveBits() generateKey() importKey() exportKey() digest()
RSASSA-PKCS1-v1_5
RSA-PSS
RSA-OAEP
ECDSA
ECDH
HMAC
AES-CTR
AES-CBC
AES-GCM
AES-KW
HKDF
PBKDF2
SHA-1
SHA-256
SHA-384
SHA-512
MD5

相关参考

本篇文档内容对您是否有帮助?
有帮助
我要反馈
提交成功!非常感谢您的反馈,我们会继续努力做到更好!