Web Crypto API#

稳定性:2 - 稳定

Node.js 提供了 Web Crypto API 标准的实现。

使用 globalThis.cryptorequire('node:crypto').webcrypto 来访问此模块。

const { subtle } = globalThis.crypto;

(async function() {

  const key = await subtle.generateKey({
    name: 'HMAC',
    hash: 'SHA-256',
    length: 256,
  }, true, ['sign', 'verify']);

  const enc = new TextEncoder();
  const message = enc.encode('I love cupcakes');

  const digest = await subtle.sign({
    name: 'HMAC',
  }, key, message);

})();

Web Cryptography API 中的现代算法#

稳定性:1.1 - 活跃开发中

Node.js 实现了 Web Cryptography API 中的现代算法 WICG 提案中的以下特性

算法

  • 'AES-OCB'1
  • 'Argon2d'2
  • 'Argon2i'2
  • 'Argon2id'2
  • 'ChaCha20-Poly1305'
  • 'cSHAKE128'
  • 'cSHAKE256'
  • 'KMAC128'1
  • 'KMAC256'1
  • 'KT128'
  • 'KT256'
  • 'ML-DSA-44'3
  • 'ML-DSA-65'3
  • 'ML-DSA-87'3
  • 'ML-KEM-512'3
  • 'ML-KEM-768'3
  • 'ML-KEM-1024'3
  • 'SHA3-256'
  • 'SHA3-384'
  • 'SHA3-512'
  • 'TurboSHAKE128'
  • 'TurboSHAKE256'

密钥格式

  • 'raw-public'
  • 'raw-secret'
  • 'raw-seed'

方法

Web Cryptography API 中的安全曲线#

稳定性:1.1 - 活跃开发中

Node.js 实现了 Web Cryptography API 中的安全曲线 WICG 提案中的以下特性

算法

  • 'Ed448'
  • 'X448'

示例#

生成密钥#

<SubtleCrypto> 类可用于生成对称(私钥)密钥或非对称密钥对(公钥和私钥)。

AES 密钥#
const { subtle } = globalThis.crypto;

async function generateAesKey(length = 256) {
  const key = await subtle.generateKey({
    name: 'AES-CBC',
    length,
  }, true, ['encrypt', 'decrypt']);

  return key;
}
ECDSA 密钥对#
const { subtle } = globalThis.crypto;

async function generateEcKey(namedCurve = 'P-521') {
  const {
    publicKey,
    privateKey,
  } = await subtle.generateKey({
    name: 'ECDSA',
    namedCurve,
  }, true, ['sign', 'verify']);

  return { publicKey, privateKey };
}
Ed25519/X25519 密钥对#
const { subtle } = globalThis.crypto;

async function generateEd25519Key() {
  return subtle.generateKey({
    name: 'Ed25519',
  }, true, ['sign', 'verify']);
}

async function generateX25519Key() {
  return subtle.generateKey({
    name: 'X25519',
  }, true, ['deriveKey']);
}
HMAC 密钥#
const { subtle } = globalThis.crypto;

async function generateHmacKey(hash = 'SHA-256') {
  const key = await subtle.generateKey({
    name: 'HMAC',
    hash,
  }, true, ['sign', 'verify']);

  return key;
}
RSA 密钥对#
const { subtle } = globalThis.crypto;
const publicExponent = new Uint8Array([1, 0, 1]);

async function generateRsaKey(modulusLength = 2048, hash = 'SHA-256') {
  const {
    publicKey,
    privateKey,
  } = await subtle.generateKey({
    name: 'RSASSA-PKCS1-v1_5',
    modulusLength,
    publicExponent,
    hash,
  }, true, ['sign', 'verify']);

  return { publicKey, privateKey };
}

加密和解密#

const crypto = globalThis.crypto;

async function aesEncrypt(plaintext) {
  const ec = new TextEncoder();
  const key = await generateAesKey();
  const iv = crypto.getRandomValues(new Uint8Array(16));

  const ciphertext = await crypto.subtle.encrypt({
    name: 'AES-CBC',
    iv,
  }, key, ec.encode(plaintext));

  return {
    key,
    iv,
    ciphertext,
  };
}

async function aesDecrypt(ciphertext, key, iv) {
  const dec = new TextDecoder();
  const plaintext = await crypto.subtle.decrypt({
    name: 'AES-CBC',
    iv,
  }, key, ciphertext);

  return dec.decode(plaintext);
}

导出和导入密钥#

const { subtle } = globalThis.crypto;

async function generateAndExportHmacKey(format = 'jwk', hash = 'SHA-512') {
  const key = await subtle.generateKey({
    name: 'HMAC',
    hash,
  }, true, ['sign', 'verify']);

  return subtle.exportKey(format, key);
}

async function importHmacKey(keyData, format = 'jwk', hash = 'SHA-512') {
  const key = await subtle.importKey(format, keyData, {
    name: 'HMAC',
    hash,
  }, true, ['sign', 'verify']);

  return key;
}

封装和解封密钥#

const { subtle } = globalThis.crypto;

async function generateAndWrapHmacKey(format = 'jwk', hash = 'SHA-512') {
  const [
    key,
    wrappingKey,
  ] = await Promise.all([
    subtle.generateKey({
      name: 'HMAC', hash,
    }, true, ['sign', 'verify']),
    subtle.generateKey({
      name: 'AES-KW',
      length: 256,
    }, true, ['wrapKey', 'unwrapKey']),
  ]);

  const wrappedKey = await subtle.wrapKey(format, key, wrappingKey, 'AES-KW');

  return { wrappedKey, wrappingKey };
}

async function unwrapHmacKey(
  wrappedKey,
  wrappingKey,
  format = 'jwk',
  hash = 'SHA-512') {

  const key = await subtle.unwrapKey(
    format,
    wrappedKey,
    wrappingKey,
    'AES-KW',
    { name: 'HMAC', hash },
    true,
    ['sign', 'verify']);

  return key;
}

签名和验证#

const { subtle } = globalThis.crypto;

async function sign(key, data) {
  const ec = new TextEncoder();
  const signature =
    await subtle.sign('RSASSA-PKCS1-v1_5', key, ec.encode(data));
  return signature;
}

async function verify(key, signature, data) {
  const ec = new TextEncoder();
  const verified =
    await subtle.verify(
      'RSASSA-PKCS1-v1_5',
      key,
      signature,
      ec.encode(data));
  return verified;
}

派生位和密钥#

const { subtle } = globalThis.crypto;

async function pbkdf2(pass, salt, iterations = 1000, length = 256) {
  const ec = new TextEncoder();
  const key = await subtle.importKey(
    'raw',
    ec.encode(pass),
    'PBKDF2',
    false,
    ['deriveBits']);
  const bits = await subtle.deriveBits({
    name: 'PBKDF2',
    hash: 'SHA-512',
    salt: ec.encode(salt),
    iterations,
  }, key, length);
  return bits;
}

async function pbkdf2Key(pass, salt, iterations = 1000, length = 256) {
  const ec = new TextEncoder();
  const keyMaterial = await subtle.importKey(
    'raw',
    ec.encode(pass),
    'PBKDF2',
    false,
    ['deriveKey']);
  const key = await subtle.deriveKey({
    name: 'PBKDF2',
    hash: 'SHA-512',
    salt: ec.encode(salt),
    iterations,
  }, keyMaterial, {
    name: 'AES-GCM',
    length,
  }, true, ['encrypt', 'decrypt']);
  return key;
}

摘要#

const { subtle } = globalThis.crypto;

async function digest(data, algorithm = 'SHA-512') {
  const ec = new TextEncoder();
  const digest = await subtle.digest(algorithm, ec.encode(data));
  return digest;
}

检查运行时算法支持#

SubtleCrypto.supports() 允许在 Web Crypto API 中进行特性检测,可用于检测给定的算法标识符(包括其参数)是否支持特定的操作。

此示例如果可用则使用 Argon2 从密码派生密钥,否则使用 PBKDF2;然后,如果可用则使用 AES-OCB 加密和解密某些文本,否则使用 AES-GCM。

const { SubtleCrypto, crypto } = globalThis;

const password = 'correct horse battery staple';
const derivationAlg =
  SubtleCrypto.supports?.('importKey', 'Argon2id') ?
    'Argon2id' :
    'PBKDF2';
const encryptionAlg =
  SubtleCrypto.supports?.('importKey', 'AES-OCB') ?
    'AES-OCB' :
    'AES-GCM';
const passwordKey = await crypto.subtle.importKey(
  derivationAlg === 'Argon2id' ? 'raw-secret' : 'raw',
  new TextEncoder().encode(password),
  derivationAlg,
  false,
  ['deriveKey'],
);
const nonce = crypto.getRandomValues(new Uint8Array(16));
const derivationParams =
  derivationAlg === 'Argon2id' ?
    {
      nonce,
      parallelism: 4,
      memory: 2 ** 21,
      passes: 1,
    } :
    {
      salt: nonce,
      iterations: 100_000,
      hash: 'SHA-256',
    };
const key = await crypto.subtle.deriveKey(
  {
    name: derivationAlg,
    ...derivationParams,
  },
  passwordKey,
  {
    name: encryptionAlg,
    length: 256,
  },
  false,
  ['encrypt', 'decrypt'],
);
const plaintext = 'Hello, world!';
const iv = crypto.getRandomValues(new Uint8Array(16));
const encrypted = await crypto.subtle.encrypt(
  { name: encryptionAlg, iv },
  key,
  new TextEncoder().encode(plaintext),
);
const decrypted = new TextDecoder().decode(await crypto.subtle.decrypt(
  { name: encryptionAlg, iv },
  key,
  encrypted,
));

算法矩阵#

表格详细说明了 Node.js Web Crypto API 实现支持的算法以及每种算法支持的 API

密钥管理 API#

算法 subtle.generateKey() subtle.exportKey() subtle.importKey() subtle.getPublicKey()
'AES-CBC'
'AES-CTR'
'AES-GCM'
'AES-KW'
'AES-OCB'
'Argon2d'
'Argon2i'
'Argon2id'
'ChaCha20-Poly1305'4
'ECDH'
'ECDSA'
'Ed25519'
'Ed448'5
'HKDF'
'HMAC'
'KMAC128'4
'KMAC256'4
'ML-DSA-44'4
'ML-DSA-65'4
'ML-DSA-87'4
'ML-KEM-512'4
'ML-KEM-768'4
'ML-KEM-1024'4
'PBKDF2'
'RSA-OAEP'
'RSA-PSS'
'RSASSA-PKCS1-v1_5'
'X25519'
'X448'5

加密操作 API#

列说明

算法 加密 签名和 MAC 密钥或位派生 密钥封装 密钥封装 摘要 (Digest)
'AES-CBC'
'AES-CTR'
'AES-GCM'
'AES-KW'
'AES-OCB'
'Argon2d'
'Argon2i'
'Argon2id'
'ChaCha20-Poly1305'4
'cSHAKE128'4
'cSHAKE256'4
'ECDH'
'ECDSA'
'Ed25519'
'Ed448'5
'HKDF'
'HMAC'
'KMAC128'4
'KMAC256'4
'KT128'4
'KT256'4
'ML-DSA-44'4
'ML-DSA-65'4
'ML-DSA-87'4
'ML-KEM-512'4
'ML-KEM-768'4
'ML-KEM-1024'4
'PBKDF2'
'RSA-OAEP'
'RSA-PSS'
'RSASSA-PKCS1-v1_5'
'SHA-1'
'SHA-256'
'SHA-384'
'SHA-512'
'SHA3-256'4
'SHA3-384'4
'SHA3-512'4
'TurboSHAKE128'4
'TurboSHAKE256'4
'X25519'
'X448'5

类:Crypto#

globalThis.cryptoCrypto 类的一个实例。Crypto 是一个单例,提供对加密 API 其余部分的访问。

crypto.subtle#

提供对 SubtleCrypto API 的访问。

crypto.getRandomValues(typedArray)#

生成加密强随机值。给定的 typedArray 将填充随机值,并返回对 typedArray 的引用。

给定的 typedArray 必须是 <TypedArray> 的基于整数的实例,即不接受 Float32ArrayFloat64Array

如果给定的 typedArray 大于 65,536 字节,将会抛出错误。

crypto.randomUUID()#

生成一个随机的 RFC 4122 第 4 版 UUID。UUID 是使用加密伪随机数生成器生成的。

类:CryptoKey#

cryptoKey.algorithm#

一个对象,详细说明了可以使用该密钥的算法以及特定于算法的附加参数。

只读。

cryptoKey.extractable#

当为 true 时,可以使用 subtle.exportKey()subtle.wrapKey() 提取 <CryptoKey>

只读。

cryptoKey.type#

  • 类型:<string> 'secret', 'private', 或 'public' 之一。

一个字符串,用于标识该密钥是对称密钥 ('secret') 还是非对称密钥 ('private''public')。

cryptoKey.usages#

一个字符串数组,用于标识可以使用该密钥的操作。

可能的用法包括:

有效的密钥用法取决于密钥算法(由 cryptokey.algorithm.name 标识)。

列说明

支持的密钥算法 加密 签名和 MAC 密钥或位派生 密钥封装 密钥封装
'AES-CBC'
'AES-CTR'
'AES-GCM'
'AES-KW'
'AES-OCB'
'Argon2d'
'Argon2i'
'Argon2id'
'ChaCha20-Poly1305'4
'ECDH'
'ECDSA'
'Ed25519'
'Ed448'5
'HDKF'
'HMAC'
'KMAC128'4
'KMAC256'4
'ML-DSA-44'4
'ML-DSA-65'4
'ML-DSA-87'4
'ML-KEM-512'4
'ML-KEM-768'4
'ML-KEM-1024'4
'PBKDF2'
'RSA-OAEP'
'RSA-PSS'
'RSASSA-PKCS1-v1_5'
'X25519'
'X448'5

类:CryptoKeyPair#

CryptoKeyPair 是一个包含 publicKeyprivateKey 属性的简单字典对象,表示非对称密钥对。

cryptoKeyPair.privateKey#

cryptoKeyPair.publicKey#

类:SubtleCrypto#

静态方法:SubtleCrypto.supports(operation, algorithm[, lengthOrAdditionalAlgorithm])#

稳定性:1.1 - 活跃开发中

  • operation <string> "encrypt", "decrypt", "sign", "verify", "digest", "generateKey", "deriveKey", "deriveBits", "importKey", "exportKey", "getPublicKey", "wrapKey", "unwrapKey", "encapsulateBits", "encapsulateKey", "decapsulateBits", 或 "decapsulateKey"
  • algorithm <string> | <Algorithm>
  • lengthOrAdditionalAlgorithm <null> | <number> | <string> | <Algorithm> | <undefined> 根据操作的不同,此参数会被忽略;或者是操作为 "deriveBits" 时的长度参数值;操作为 "deriveKey" 时要派生的密钥的算法;操作为 "wrapKey" 时包装前要导出的密钥的算法;操作为 "unwrapKey" 时解包后要导入的密钥的算法;或者在操作为 "encapsulateKey" 或 "decapsulateKey" 时 en/decapsulating 密钥后要导入的密钥的算法。默认值: 操作为 "deriveBits" 时为 null,否则为 undefined
  • 返回:<boolean> 指示实现是否支持给定的操作

允许在 Web Crypto API 中进行特性检测,可用于检测给定的算法标识符(包括其参数)是否支持特定的操作。

有关此方法的使用示例,请参阅 检查运行时算法支持

subtle.decapsulateBits(decapsulationAlgorithm, decapsulationKey, ciphertext)#

稳定性:1.1 - 活跃开发中

消息接收者使用其非对称私钥解密“封装密钥”(密文),从而恢复临时对称密钥(表示为 <ArrayBuffer>),然后使用该密钥解密消息。

目前支持的算法包括

  • 'ML-KEM-512'4
  • 'ML-KEM-768'4
  • 'ML-KEM-1024'4

subtle.decapsulateKey(decapsulationAlgorithm, decapsulationKey, ciphertext, sharedKeyAlgorithm, extractable, usages)#

稳定性:1.1 - 活跃开发中

消息接收者使用其非对称私钥解密“封装密钥”(密文),从而恢复临时对称密钥(表示为 <CryptoKey>),然后使用该密钥解密消息。

目前支持的算法包括

  • 'ML-KEM-512'4
  • 'ML-KEM-768'4
  • 'ML-KEM-1024'4

subtle.decrypt(algorithm, key, data)#

使用 algorithm 中指定的方法和参数以及 key 提供的密钥材料,此方法尝试解密提供的 data。如果成功,返回的 promise 将以包含明文结果的 <ArrayBuffer> 解析。

目前支持的算法包括

  • 'AES-CBC'
  • 'AES-CTR'
  • 'AES-GCM'
  • 'AES-OCB'4
  • 'ChaCha20-Poly1305'4
  • 'RSA-OAEP'

subtle.deriveBits(algorithm, baseKey[, length])#

使用 algorithm 中指定的方法和参数以及 baseKey 提供的密钥材料,此方法尝试生成 length 位。

当未提供 length 或为 null 时,将为给定算法生成最大位数的位。这对于 'ECDH', 'X25519', 和 'X448'5 算法是允许的,对于其他算法,length 必须是一个数字。

如果成功,返回的 promise 将以包含生成数据的 <ArrayBuffer> 解析。

目前支持的算法包括

  • 'Argon2d'4
  • 'Argon2i'4
  • 'Argon2id'4
  • 'ECDH'
  • 'HKDF'
  • 'PBKDF2'
  • 'X25519'
  • 'X448'5

subtle.deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages)#

使用 algorithm 中指定的方法和参数以及 baseKey 提供的密钥材料,此方法尝试根据 derivedKeyAlgorithm 中的方法和参数生成一个新的 <CryptoKey>

调用此方法等同于调用 subtle.deriveBits() 生成原始密钥材料,然后使用 deriveKeyAlgorithm, extractable, 和 keyUsages 参数作为输入,将结果传入 subtle.importKey() 方法。

目前支持的算法包括

  • 'Argon2d'4
  • 'Argon2i'4
  • 'Argon2id'4
  • 'ECDH'
  • 'HKDF'
  • 'PBKDF2'
  • 'X25519'
  • 'X448'5

subtle.digest(algorithm, data)#

使用 algorithm 标识的方法,此方法尝试生成 data 的摘要。如果成功,返回的 promise 将以包含计算出的摘要的 <ArrayBuffer> 解析。

如果 algorithm 作为 <string> 提供,则它必须是以下之一

  • 'cSHAKE128'4
  • 'cSHAKE256'4
  • 'KT128'4
  • 'KT256'4
  • 'SHA-1'
  • 'SHA-256'
  • 'SHA-384'
  • 'SHA-512'
  • 'SHA3-256'4
  • 'SHA3-384'4
  • 'SHA3-512'4
  • 'TurboSHAKE128'4
  • 'TurboSHAKE256'4

如果 algorithm 作为 <Object> 提供,它必须具有一个 name 属性,其值是上述值之一。

subtle.encapsulateBits(encapsulationAlgorithm, encapsulationKey)#

稳定性:1.1 - 活跃开发中

使用消息接收者的非对称公钥加密临时对称密钥。此加密的密钥即为表示为 {EncapsulatedBits} 的“封装密钥”。

目前支持的算法包括

  • 'ML-KEM-512'4
  • 'ML-KEM-768'4
  • 'ML-KEM-1024'4

subtle.encapsulateKey(encapsulationAlgorithm, encapsulationKey, sharedKeyAlgorithm, extractable, usages)#

稳定性:1.1 - 活跃开发中

使用消息接收者的非对称公钥加密临时对称密钥。此加密的密钥即为表示为 {EncapsulatedKey} 的“封装密钥”。

目前支持的算法包括

  • 'ML-KEM-512'4
  • 'ML-KEM-768'4
  • 'ML-KEM-1024'4

subtle.encrypt(algorithm, key, data)#

使用 algorithm 指定的方法和参数以及 key 提供的密钥材料,此方法尝试加密 data。如果成功,返回的 promise 将以包含加密结果的 <ArrayBuffer> 解析。

目前支持的算法包括

  • 'AES-CBC'
  • 'AES-CTR'
  • 'AES-GCM'
  • 'AES-OCB'4
  • 'ChaCha20-Poly1305'4
  • 'RSA-OAEP'

subtle.exportKey(format, key)#

将给定密钥导出为指定格式(如果支持)。

如果 <CryptoKey> 不可提取,则返回的 promise 将拒绝。

format'pkcs8''spki' 且导出成功时,返回的 promise 将以包含导出的密钥数据的 <ArrayBuffer> 解析。

format'jwk' 且导出成功时,返回的 promise 将以符合 JSON Web Key 规范的 JavaScript 对象解析。

支持的密钥算法 'spki' 'pkcs8' 'jwk' 'raw' 'raw-secret' 'raw-public' 'raw-seed'
'AES-CBC'
'AES-CTR'
'AES-GCM'
'AES-KW'
'AES-OCB'4
'ChaCha20-Poly1305'4
'ECDH'
'ECDSA'
'Ed25519'
'Ed448'5
'HMAC'
'KMAC128'4
'KMAC256'4
'ML-DSA-44'4
'ML-DSA-65'4
'ML-DSA-87'4
'ML-KEM-512'4
'ML-KEM-768'4
'ML-KEM-1024'4
'RSA-OAEP'
'RSA-PSS'
'RSASSA-PKCS1-v1_5'

subtle.getPublicKey(key, keyUsages)#

稳定性:1.1 - 活跃开发中

从给定的私钥派生公钥。

subtle.generateKey(algorithm, extractable, keyUsages)#

使用 algorithm 中提供的参数,此方法尝试生成新的密钥材料。根据所使用的算法,生成单个 <CryptoKey><CryptoKeyPair>

支持生成 <CryptoKeyPair>(公钥和私钥)的算法包括

  • 'ECDH'
  • 'ECDSA'
  • 'Ed25519'
  • 'Ed448'5
  • 'ML-DSA-44'4
  • 'ML-DSA-65'4
  • 'ML-DSA-87'4
  • 'ML-KEM-512'4
  • 'ML-KEM-768'4
  • 'ML-KEM-1024'4
  • 'RSA-OAEP'
  • 'RSA-PSS'
  • 'RSASSA-PKCS1-v1_5'
  • 'X25519'
  • 'X448'5

支持生成 <CryptoKey>(私钥)的算法包括

  • 'AES-CBC'
  • 'AES-CTR'
  • 'AES-GCM'
  • 'AES-KW'
  • 'AES-OCB'4
  • 'ChaCha20-Poly1305'4
  • 'HMAC'
  • 'KMAC128'4
  • 'KMAC256'4

subtle.importKey(format, keyData, algorithm, extractable, keyUsages)#

此方法尝试将提供的 keyData 解释为给定的 format,以使用提供的 algorithm, extractable, 和 keyUsages 参数创建 <CryptoKey> 实例。如果导入成功,返回的 promise 将以密钥材料的 <CryptoKey> 表示形式解析。

如果导入 KDF 算法密钥,extractable 必须为 false

目前支持的算法包括

支持的密钥算法 'spki' 'pkcs8' 'jwk' 'raw' 'raw-secret' 'raw-public' 'raw-seed'
'AES-CBC'
'AES-CTR'
'AES-GCM'
'AES-KW'
'AES-OCB'4
'Argon2d'4
'Argon2i'4
'Argon2id'4
'ChaCha20-Poly1305'4
'ECDH'
'ECDSA'
'Ed25519'
'Ed448'5
'HDKF'
'HMAC'
'KMAC128'4
'KMAC256'4
'ML-DSA-44'4
'ML-DSA-65'4
'ML-DSA-87'4
'ML-KEM-512'4
'ML-KEM-768'4
'ML-KEM-1024'4
'PBKDF2'
'RSA-OAEP'
'RSA-PSS'
'RSASSA-PKCS1-v1_5'
'X25519'
'X448'5

subtle.sign(algorithm, key, data)#

使用 algorithm 给定的方法和参数以及 key 提供的密钥材料,此方法尝试生成 data 的加密签名。如果成功,返回的 promise 将以包含生成的签名的 <ArrayBuffer> 解析。

目前支持的算法包括

  • 'ECDSA'
  • 'Ed25519'
  • 'Ed448'5
  • 'HMAC'
  • 'KMAC128'4
  • 'KMAC256'4
  • 'ML-DSA-44'4
  • 'ML-DSA-65'4
  • 'ML-DSA-87'4
  • 'RSA-PSS'
  • 'RSASSA-PKCS1-v1_5'

subtle.unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgo, unwrappedKeyAlgo, extractable, keyUsages)#

在密码学中,“封装密钥”是指导出并加密密钥材料。此方法尝试解密封装的密钥并创建一个 <CryptoKey> 实例。它等同于先对加密的密钥数据调用 subtle.decrypt()(使用 wrappedKey, unwrapAlgo, 和 unwrappingKey 参数作为输入),然后将结果传入 subtle.importKey() 方法(使用 unwrappedKeyAlgo, extractable, 和 keyUsages 参数作为输入)。如果成功,返回的 promise 将以 <CryptoKey> 对象解析。

当前支持的封装算法包括

  • 'AES-CBC'
  • 'AES-CTR'
  • 'AES-GCM'
  • 'AES-KW'
  • 'AES-OCB'4
  • 'ChaCha20-Poly1305'4
  • 'RSA-OAEP'

支持的解封装密钥算法包括

  • 'AES-CBC'
  • 'AES-CTR'
  • 'AES-GCM'
  • 'AES-KW'
  • 'AES-OCB'4
  • 'ChaCha20-Poly1305'4
  • 'ECDH'
  • 'ECDSA'
  • 'Ed25519'
  • 'Ed448'5
  • 'HMAC'
  • 'KMAC128'5
  • 'KMAC256'5
  • 'ML-DSA-44'4
  • 'ML-DSA-65'4
  • 'ML-DSA-87'4
  • 'ML-KEM-512'4
  • 'ML-KEM-768'4
  • 'ML-KEM-1024'4v
  • 'RSA-OAEP'
  • 'RSA-PSS'
  • 'RSASSA-PKCS1-v1_5'
  • 'X25519'
  • 'X448'5

subtle.verify(algorithm, key, signature, data)#

使用 algorithm 中给定的方法和参数以及 key 提供的密钥材料,此方法尝试验证 signature 是否为 data 的有效加密签名。返回的 promise 将以 truefalse 解析。

目前支持的算法包括

  • 'ECDSA'
  • 'Ed25519'
  • 'Ed448'5
  • 'HMAC'
  • 'KMAC128'5
  • 'KMAC256'5
  • 'ML-DSA-44'4
  • 'ML-DSA-65'4
  • 'ML-DSA-87'4
  • 'RSA-PSS'
  • 'RSASSA-PKCS1-v1_5'

subtle.wrapKey(format, key, wrappingKey, wrapAlgo)#

在密码学中,“封装密钥”是指导出并加密密钥材料。此方法将密钥材料导出为 format 标识的格式,然后使用 wrapAlgo 指定的方法和参数以及 wrappingKey 提供的密钥材料进行加密。它等同于调用 subtle.exportKey()(使用 formatkey 作为参数),然后将结果传入 subtle.encrypt() 方法(使用 wrappingKeywrapAlgo 作为输入)。如果成功,返回的 promise 将以包含加密密钥数据的 <ArrayBuffer> 解析。

当前支持的封装算法包括

  • 'AES-CBC'
  • 'AES-CTR'
  • 'AES-GCM'
  • 'AES-KW'
  • 'AES-OCB'4
  • 'ChaCha20-Poly1305'4
  • 'RSA-OAEP'

算法参数#

算法参数对象定义了各种 <SubtleCrypto> 方法使用的方法和参数。虽然此处描述为“类”,但它们是简单的 JavaScript 字典对象。

类:Algorithm#

Algorithm.name#

类:AeadParams#

aeadParams.additionalData#

未加密但包含在数据身份验证中的额外输入。additionalData 的使用是可选的。

aeadParams.iv#

初始化向量对于使用给定密钥的每次加密操作必须是唯一的。

aeadParams.name#
  • 类型:<string> 必须是 'AES-GCM', 'AES-OCB', 或 'ChaCha20-Poly1305'
aeadParams.tagLength#
  • 类型:<number> 生成的身份验证标签的大小(以位为单位)。

类:AesDerivedKeyParams#

aesDerivedKeyParams.name#
  • 类型:<string> 必须是 'AES-CBC', 'AES-CTR', 'AES-GCM', 'AES-OCB', 或 'AES-KW' 之一
aesDerivedKeyParams.length#

要派生的 AES 密钥的长度。必须是 128, 192, 或 256

类:AesCbcParams#

aesCbcParams.iv#

提供初始化向量。它必须正好 16 字节长,并且应该是不可预测和加密随机的。

aesCbcParams.name#
  • 类型:<string> 必须是 'AES-CBC'

类:AesCtrParams#

aesCtrParams.counter#

计数器块的初始值。这必须正好 16 字节长。

AES-CTR 方法使用块中最右边的 length 位作为计数器,剩余的位作为 nonce。

aesCtrParams.length#
  • 类型:<number> aesCtrParams.counter 中要用作计数器的位数。
aesCtrParams.name#
  • 类型:<string> 必须是 'AES-CTR'

类:AesKeyAlgorithm#

aesKeyAlgorithm.length#

AES 密钥的长度(以位为单位)。

aesKeyAlgorithm.name#

类:AesKeyGenParams#

aesKeyGenParams.length#

要生成的 AES 密钥的长度。必须是 128, 192, 或 256

aesKeyGenParams.name#
  • 类型:<string> 必须是 'AES-CBC', 'AES-CTR', 'AES-GCM', 或 'AES-KW' 之一

类:Argon2Params#

argon2Params.associatedData#

表示可选的关联数据。

argon2Params.memory#

表示内存大小(以 KiB 为单位)。它必须至少是并行度的 8 倍。

argon2Params.name#
  • 类型:<string> 必须是 'Argon2d', 'Argon2i', 或 'Argon2id' 之一。
argon2Params.nonce#

表示 nonce,它是密码哈希应用程序的盐。

argon2Params.parallelism#

表示并行度。

argon2Params.passes#

表示通过次数。

argon2Params.secretValue#

表示可选的密钥值。

argon2Params.version#

表示 Argon2 版本号。默认且目前唯一定义的版本是 19 (0x13)。

类:ContextParams#

contextParams.name#
  • 类型:<string> 必须是 Ed4485, 'ML-DSA-44'4, 'ML-DSA-65'4, 或 'ML-DSA-87'4
contextParams.context#

context 成员表示要与消息关联的可选上下文数据。

类:CShakeParams#

cShakeParams.name#
  • 类型:<string> 必须是 'cSHAKE128'4'cSHAKE256'4
cShakeParams.outputLength#
  • 类型:<number> 表示请求的输出长度(以位为单位)。
cShakeParams.functionName#

functionName 成员表示函数名称,NIST 使用它来定义基于 cSHAKE 的函数。Node.js Web Crypto API 实现仅支持零长度的 functionName,这等同于不提供 functionName。

cShakeParams.customization#

customization 成员表示自定义字符串。Node.js Web Crypto API 实现仅支持零长度的 customization,这等同于不提供 customization。

类:EcdhKeyDeriveParams#

ecdhKeyDeriveParams.name#
  • 类型:<string> 必须是 'ECDH', 'X25519', 或 'X448'5
ecdhKeyDeriveParams.public#

ECDH 密钥派生操作通过输入一方的私钥和另一方的公钥来运行——利用两者生成共同的共享密钥。ecdhKeyDeriveParams.public 属性设置为另一方的公钥。

类:EcdsaParams#

ecdsaParams.hash#

如果表示为 <string>,则该值必须是以下之一

  • 'SHA-1'
  • 'SHA-256'
  • 'SHA-384'
  • 'SHA-512'
  • 'SHA3-256'4
  • 'SHA3-384'4
  • 'SHA3-512'4

如果表示为 <Algorithm>,该对象的 name 属性必须是上述列表中的值。

ecdsaParams.name#
  • 类型:<string> 必须为 'ECDSA'

类:EcKeyAlgorithm#

ecKeyAlgorithm.name#
ecKeyAlgorithm.namedCurve#

类:EcKeyGenParams#

ecKeyGenParams.name#
  • 类型:<string> 必须为 'ECDSA''ECDH' 之一。
ecKeyGenParams.namedCurve#
  • 类型:<string> 必须为 'P-256''P-384''P-521' 之一。

类:EcKeyImportParams#

ecKeyImportParams.name#
  • 类型:<string> 必须为 'ECDSA''ECDH' 之一。
ecKeyImportParams.namedCurve#
  • 类型:<string> 必须为 'P-256''P-384''P-521' 之一。

类:EncapsulatedBits#

用于消息加密的临时对称密钥(表示为 <ArrayBuffer>)以及由该共享密钥加密的密文(可与消息一起传输给消息接收者)。接收者使用其私钥来确定共享密钥,从而解密消息。

encapsulatedBits.ciphertext#
encapsulatedBits.sharedKey#

类:EncapsulatedKey#

用于消息加密的临时对称密钥(表示为 <CryptoKey>)以及由该共享密钥加密的密文(可与消息一起传输给消息接收者)。接收者使用其私钥来确定共享密钥,从而解密消息。

encapsulatedKey.ciphertext#
encapsulatedKey.sharedKey#

类:HkdfParams#

hkdfParams.hash#

如果表示为 <string>,则该值必须是以下之一

  • 'SHA-1'
  • 'SHA-256'
  • 'SHA-384'
  • 'SHA-512'
  • 'SHA3-256'4
  • 'SHA3-384'4
  • 'SHA3-512'4

如果表示为 <Algorithm>,该对象的 name 属性必须是上述列表中的值。

hkdfParams.info#

为 HKDF 算法提供应用特定的上下文输入。它可以是零长度,但必须提供。

hkdfParams.name#
hkdfParams.salt#

Salt 值能显著提高 HKDF 算法的强度。它应该是随机或伪随机的,并且长度应与摘要函数的输出长度相同(例如,如果使用 'SHA-256' 作为摘要函数,salt 应该是 256 位的随机数据)。

类:HmacImportParams#

hmacImportParams.hash#

如果表示为 <string>,则该值必须是以下之一

  • 'SHA-1'
  • 'SHA-256'
  • 'SHA-384'
  • 'SHA-512'
  • 'SHA3-256'4
  • 'SHA3-384'4
  • 'SHA3-512'4

如果表示为 <Algorithm>,该对象的 name 属性必须是上述列表中的值。

hmacImportParams.length#

可选的 HMAC 密钥位数。这是可选的,大多数情况下应省略。

hmacImportParams.name#

类:HmacKeyAlgorithm#

hmacKeyAlgorithm.hash#
hmacKeyAlgorithm.length#

HMAC 密钥的长度(以位为单位)。

hmacKeyAlgorithm.name#

类:HmacKeyGenParams#

hmacKeyGenParams.hash#

如果表示为 <string>,则该值必须是以下之一

  • 'SHA-1'
  • 'SHA-256'
  • 'SHA-384'
  • 'SHA-512'
  • 'SHA3-256'4
  • 'SHA3-384'4
  • 'SHA3-512'4

如果表示为 <Algorithm>,该对象的 name 属性必须是上述列表中的值。

hmacKeyGenParams.length#

要生成的 HMAC 密钥的位数。如果省略,长度将由所使用的哈希算法决定。这是可选的,大多数情况下应省略。

hmacKeyGenParams.name#

类:KeyAlgorithm#

keyAlgorithm.name#

类:KangarooTwelveParams#

kangarooTwelveParams.customization#

KangarooTwelve 的可选自定义字符串。

kangarooTwelveParams.name#
  • 类型:<string> 必须为 'KT128'4'KT256'4
kangarooTwelveParams.outputLength#
  • 类型:<number> 表示请求的输出长度(以位为单位)。

类:KmacImportParams#

kmacImportParams.length#

可选的 KMAC 密钥位数。这是可选的,大多数情况下应省略。

kmacImportParams.name#
  • 类型:<string> 必须为 'KMAC128''KMAC256'

类:KmacKeyAlgorithm#

kmacKeyAlgorithm.length#

KMAC 密钥的长度(以位为单位)。

kmacKeyAlgorithm.name#

类:KmacKeyGenParams#

kmacKeyGenParams.length#

要生成的 KMAC 密钥的位数。如果省略,长度将由所使用的 KMAC 算法决定。这是可选的,大多数情况下应省略。

kmacKeyGenParams.name#
  • 类型:<string> 必须为 'KMAC128''KMAC256'

类:KmacParams#

kmacParams.algorithm#
  • 类型:<string> 必须为 'KMAC128''KMAC256'
kmacParams.outputLength#

输出长度(以字节为单位)。必须是一个正整数。

kmacParams.customization#

customization 成员表示可选的自定义字符串。

类:Pbkdf2Params#

pbkdf2Params.hash#

如果表示为 <string>,则该值必须是以下之一

  • 'SHA-1'
  • 'SHA-256'
  • 'SHA-384'
  • 'SHA-512'
  • 'SHA3-256'4
  • 'SHA3-384'4
  • 'SHA3-512'4

如果表示为 <Algorithm>,该对象的 name 属性必须是上述列表中的值。

pbkdf2Params.iterations#

PBKDF2 算法在派生位数时应进行的迭代次数。

pbkdf2Params.name#
  • 类型:<string> 必须为 'PBKDF2'
pbkdf2Params.salt#

应该至少包含 16 个随机或伪随机字节。

类:RsaHashedImportParams#

rsaHashedImportParams.hash#

如果表示为 <string>,则该值必须是以下之一

  • 'SHA-1'
  • 'SHA-256'
  • 'SHA-384'
  • 'SHA-512'
  • 'SHA3-256'4
  • 'SHA3-384'4
  • 'SHA3-512'4

如果表示为 <Algorithm>,该对象的 name 属性必须是上述列表中的值。

rsaHashedImportParams.name#
  • 类型:<string> 必须为 'RSASSA-PKCS1-v1_5''RSA-PSS''RSA-OAEP' 之一。

类:RsaHashedKeyAlgorithm#

rsaHashedKeyAlgorithm.hash#
rsaHashedKeyAlgorithm.modulusLength#

RSA 模数的长度(以位为单位)。

rsaHashedKeyAlgorithm.name#
rsaHashedKeyAlgorithm.publicExponent#

RSA 公共指数。

类:RsaHashedKeyGenParams#

rsaHashedKeyGenParams.hash#

如果表示为 <string>,则该值必须是以下之一

  • 'SHA-1'
  • 'SHA-256'
  • 'SHA-384'
  • 'SHA-512'
  • 'SHA3-256'4
  • 'SHA3-384'4
  • 'SHA3-512'4

如果表示为 <Algorithm>,该对象的 name 属性必须是上述列表中的值。

rsaHashedKeyGenParams.modulusLength#

RSA 模数的长度(以位为单位)。作为最佳实践,应至少为 2048

rsaHashedKeyGenParams.name#
  • 类型:<string> 必须为 'RSASSA-PKCS1-v1_5''RSA-PSS''RSA-OAEP' 之一。
rsaHashedKeyGenParams.publicExponent#

RSA 公共指数。必须是一个包含大端无符号整数的 <Uint8Array>,该整数必须在 32 位以内。该 <Uint8Array> 可以包含任意数量的前导零位。该值必须是素数。除非有理由使用其他值,否则请使用 new Uint8Array([1, 0, 1]) (65537) 作为公共指数。

类:RsaOaepParams#

rsaOaepParams.label#

一组额外的字节,它们不会被加密,但会与生成的密文绑定。

rsaOaepParams.label 参数是可选的。

rsaOaepParams.name#
  • 类型:<string> 必须为 'RSA-OAEP'

类:RsaPssParams#

rsaPssParams.name#
  • 类型:<string> 必须为 'RSA-PSS'
rsaPssParams.saltLength#

要使用的随机 salt 的长度(以字节为单位)。

类:TurboShakeParams#

turboShakeParams.domainSeparation#

可选的域分离字节 (0x01-0x7f)。默认为 0x1f

turboShakeParams.name#
  • 类型:<string> 必须为 'TurboSHAKE128'4'TurboSHAKE256'4
turboShakeParams.outputLength#
  • 类型:<number> 表示请求的输出长度(以位为单位)。

脚注

  1. 需要 OpenSSL >= 3.0 2 3

  2. 需要 OpenSSL >= 3.2 2 3

  3. 需要 OpenSSL >= 3.5 2 3 4 5 6

  4. 参见 Web 密码 API 中的现代算法 2 ...(此处省略后续重复的注脚链接)

  5. 参见 Web 密码 API 中的安全曲线 2 ...(此处省略后续重复的注脚链接)