SubtleCrypto.encrypt() - Web API 接口参考 编辑

SubtleCrypto.encrypt() 方法以算法、密钥、明文为参数返回一个包含加密数据的 Promise 对象。

语法

var result = crypto.encrypt(algo, key, cleartext);

参数

  • algo 是一个使用加密函数的对象或者 DOMString,后者是 {"name": algo} 的缩写。支持的值是:
    • {"name": "AES-CBC", iv} iv 是具有16个随机字节的 ArrayBufferArrayBufferView  (这些应该由 RandomSource.getRandomValues() 生成)。
    • {"name": "AES-CTR", counter, length}
    • {"name": "AES-GCM", iv, additionalData, tagLength} (additionalDatatagLength 是可选的)
    • {"name": "RSA-OAEP", label} (label 是可选的)
  • key 是一个包含签名密钥的 CryptoKey
  • cleartext是一个包含需要加密的明文 ArrayBuffer 或者 ArrayBufferView 对象。

返回值

异常

当遇到以下异常时,promise 将会返回一次错误(reject):

InvalidAccessError
当针对提供的 key 值执行的操作无效时(例如加密算法或者 key 值无效),将会抛出该错误。
OperationError
发生于由于特定于操作的原因使得操作失败时,例如算法参数的大小无效,或者 AES-GCM 明文长度超过 2³⁹−256 字节。

支持的算法

Crypto 接口提供了支持 encrypt() 和 decrypt() 操作的四种算法。

其中的 RSA-OAEP 算法是一种非对称加密的公钥密码(public-key cryptosystem)。

其它三种算法则都是对称密钥加密(symmetric algorithms),并且它们都是基于同一种基础加密,即 AES (Advanced Encryption Standard)。它们不同之处在于分组加密的操作方式(mode)。Crypto 接口支持以下三种 AES 加密类型:

  • CTR (Counter Mode)
  • CBC (Cipher Block Chaining)
  • GCM (Galois/Counter Mode)

这里强烈建议使用认证加密authenticated encryption),它可以检测密文是否已被攻击者篡改。使用认证也可以避免选择密文攻击chosen-ciphertext attacks),即攻击者可以请求系统解密任意的消息,然后使用解密结果来倒推出关于密钥的一些信息。虽然 CTR 和 CBC 模式可以添加认证,但是它们默认不提供该操作,并且在手动实现它们的时候,很同意犯一些微小但严重的错误。GCM 不支持内置的认证,由于这个原因,常常推荐使用另外两种  AES 加密算法。

RSA-OAEP

关于 RSA-OAEP 公钥加密算法的规范位于 RFC 3447

AES-CTR

使用 Counter 模式的 AES 算法,相关规范位于 NIST SP800-38A

AES-CBC

使用 Cipher Block Chaining 模式的 AES 算法,规范位于NIST SP800-38A

AES-GCM

使用 Galois/Counter 模式的 AES 算法,规范位于 NIST SP800-38D

这种模式与上面的模式不同之处在于,GCM 是一种 "认证(authenticated)" 模式,意思就是它包含了检测密文是否未被攻击者篡改的功能。

示例

注意: 你可以在 GitHub 尝试这个示例(try the working examples)。

RSA-OAEP

以下代码获取文本框中的内容,编码后进行加密,使用的算法为 RSA-OAEP。可以在 GitHub 查看完整代码:See the complete code on GitHub

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 模式加密,完整代码:See the complete code on GitHub

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
  );
}
let iv = new Uint8array(16);
let key = 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 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 模式加密,完整代码:See the complete code on GitHub

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
    },
    key,
    encoded
  );
}

AES-GCM

使用 AES 的 GCM 模式加密,完整代码:See the complete code on GitHub

function getMessageEncoding() {
  const messageBox = document.querySelector(".aes-gcm #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(12));
  return window.crypto.subtle.encrypt(
    {
      name: "AES-GCM",
      iv: iv
    },
    key,
    encoded
  );
}

规范

SpecificationStatusComment
Web Cryptography API
SubtleCrypto.encrypt()
RecommendationInitial definition.

浏览器兼容性

BCD tables only load in the browser

The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

另见

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

词条统计

浏览:98 次

字数:11875

最后编辑:7 年前

编辑次数:0 次

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文