SubtleCrypto: encrypt() 方法

基线 广泛可用

此功能已经成熟,并在许多设备和浏览器版本上运行。它自 2015 年 7 月.

安全上下文:此功能仅在 安全上下文 (HTTPS) 中可用,在某些或所有 支持的浏览器 中可用。

SubtleCrypto 接口的 encrypt() 方法对数据进行加密。

它接受以下参数:用于加密的 密钥、一些特定于算法的参数,以及要加密的数据(也称为“明文”)。它返回一个 Promise,该承诺将以加密后的数据(也称为“密文”)作为结果。

语法

js
encrypt(algorithm, key, data)

参数

algorithm

一个对象,指定要使用的 算法 以及任何必需的额外参数

key

一个 CryptoKey,包含用于加密的密钥。

data

一个 ArrayBuffer、一个 TypedArray 或一个 DataView,包含要加密的数据(也称为 明文)。

返回值

一个 Promise,以包含“密文”的 ArrayBuffer 作为结果。

异常

当遇到以下异常时,承诺将被拒绝

InvalidAccessError DOMException

当请求的操作对于提供的密钥无效时引发(例如,无效的加密算法,或特定加密算法的无效密钥)。

OperationError DOMException

当操作因特定于操作的原因而失败时引发(例如,算法参数大小无效,或 AES-GCM 明文长度超过 239−256 字节)。

支持的算法

Web Crypto API 提供四种支持 encrypt()decrypt() 操作的算法。

其中一种算法 — RSA-OAEP — 是一种 公钥密码系统

这里介绍的其他三种加密算法都是 对称算法,它们都基于相同的底层密码 AES(高级加密标准)。它们之间的区别在于 模式。Web Crypto API 支持三种不同的 AES 模式

  • CTR(计数器模式)
  • CBC(密码分组链接)
  • GCM(伽罗瓦/计数器模式)

强烈建议使用带认证的加密,其中包括检查密文是否被攻击者修改。认证有助于防止选择密文攻击,在这种攻击中,攻击者可以要求系统解密任意消息,并使用结果来推断有关密钥的信息。虽然可以向 CTR 和 CBC 模式添加认证,但它们默认情况下不提供认证,并且在手动实现它时,很容易犯一些微小但严重的错误。GCM 提供了内置认证,因此通常建议使用它而不是其他两种 AES 模式。

RSA-OAEP

RSA-OAEP 公钥加密系统在 RFC 3447 中指定。

AES-CTR

这表示 AES 采用计数器模式,如 NIST SP800-38A 中所述。

AES 是一种分组密码,这意味着它将消息分成块,并一次加密一个块。在 CTR 模式下,每次加密消息的块时,都会混合一个额外的数据块。这个额外的数据块被称为“计数器块”。

给定一个计数器块值,对于同一个密钥,它永远不能被使用超过一次

  • 给定一个长为 n 个块的消息,每个块必须使用不同的计数器块。
  • 如果同一个密钥用于加密多个消息,那么所有消息的所有块必须使用不同的计数器块。

这通常是通过将初始计数器块值分成两个连接的部分来实现的

  • 一个 nonce(即,一个只能使用一次的数字)。nonce 部分在消息的每个块中保持不变。每次要加密新的消息时,都会选择一个新的 nonce。nonce 不需要保密,但不能在使用同一个密钥时重复使用。
  • 一个计数器。这个部分在每次加密块时都会递增。

本质上:nonce 应该确保计数器块不会从一个消息重用到另一个消息,而计数器应该确保计数器块不会在一个消息内被重用。

注意:有关详细信息,请参阅 NIST SP800-38A 标准的附录 B

AES-CBC

这表示 AES 采用密码分组链接模式,如 NIST SP800-38A 中所述。

AES-GCM

这表示 AES 采用伽罗瓦/计数器模式,如 NIST SP800-38D 中所述。

这种模式与其他模式的一个主要区别是,GCM 是一种“带认证的”模式,这意味着它包括检查密文是否被攻击者修改。

示例

注意:你可以在 GitHub 上 尝试运行示例

RSA-OAEP

此代码获取文本框的内容,对其进行编码以供加密,并使用 RSA-OAEP 进行加密。 在 GitHub 上查看完整的代码

js
function getMessageEncoding() {
  const messageBox = document.querySelector(".rsa-oaep #message");
  let message = messageBox.value;
  let enc = new TextEncoder();
  return enc.encode(message);
}

function encryptMessage(publicKey) {
  let encoded = getMessageEncoding();
  return window.crypto.subtle.encrypt(
    {
      name: "RSA-OAEP",
    },
    publicKey,
    encoded,
  );
}

AES-CTR

此代码获取文本框的内容,对其进行编码以供加密,并使用 AES 采用 CTR 模式进行加密。 在 GitHub 上查看完整的代码

js
function getMessageEncoding() {
  const messageBox = document.querySelector(".aes-ctr #message");
  let message = messageBox.value;
  let enc = new TextEncoder();
  return enc.encode(message);
}

function encryptMessage(key) {
  let encoded = getMessageEncoding();
  // counter will be needed for decryption
  counter = window.crypto.getRandomValues(new Uint8Array(16));
  return window.crypto.subtle.encrypt(
    {
      name: "AES-CTR",
      counter,
      length: 64,
    },
    key,
    encoded,
  );
}
js
let iv = window.crypto.getRandomValues(new Uint8Array(16));
let key = window.crypto.getRandomValues(new Uint8Array(16));
let data = new Uint8Array(12345);
// crypto functions are wrapped in promises so we have to use await and make sure the function that
// contains this code is an async function
// encrypt function wants a cryptokey object
const key_encoded = await window.crypto.subtle.importKey(
  "raw",
  key.buffer,
  "AES-CTR",
  false,
  ["encrypt", "decrypt"],
);
const encrypted_content = await window.crypto.subtle.encrypt(
  {
    name: "AES-CTR",
    counter: iv,
    length: 128,
  },
  key_encoded,
  data,
);

// Uint8Array
console.log(encrypted_content);

AES-CBC

此代码获取文本框的内容,对其进行编码以供加密,并使用 AES 采用 CBC 模式进行加密。 在 GitHub 上查看完整的代码

js
function getMessageEncoding() {
  const messageBox = document.querySelector(".aes-cbc #message");
  let message = messageBox.value;
  let enc = new TextEncoder();
  return enc.encode(message);
}

function encryptMessage(key) {
  let encoded = getMessageEncoding();
  // iv will be needed for decryption
  iv = window.crypto.getRandomValues(new Uint8Array(16));
  return window.crypto.subtle.encrypt(
    {
      name: "AES-CBC",
      iv: iv,
    },
    key,
    encoded,
  );
}

AES-GCM

此代码获取文本框的内容,对其进行编码以供加密,并使用 AES 采用 GCM 模式进行加密。 在 GitHub 上查看完整的代码

js
function getMessageEncoding() {
  const messageBox = document.querySelector(".aes-gcm #message");
  const message = messageBox.value;
  const enc = new TextEncoder();
  return enc.encode(message);
}

function encryptMessage(key) {
  const encoded = getMessageEncoding();
  // iv will be needed for decryption
  const iv = window.crypto.getRandomValues(new Uint8Array(12));
  return window.crypto.subtle.encrypt(
    { name: "AES-GCM", iv: iv },
    key,
    encoded,
  );
}

规范

规范
Web Cryptography API
# SubtleCrypto-method-encrypt

浏览器兼容性

BCD 表格仅在浏览器中加载

另请参阅