SubtleCrypto: encrypt() 方法
注意:此功能在 Web Workers 中可用。
SubtleCrypto 接口的 encrypt() 方法用于加密数据。
它接收以下参数:用于加密的密钥、特定于算法的参数以及要加密的数据(也称为“明文”)。它返回一个 Promise,该 Promise 将以加密后的数据(也称为“密文”)来fulfilled。
语法
encrypt(algorithm, key, data)
参数
algorithm-
一个对象,指定要使用的算法以及任何需要的额外参数
- 要使用 RSA-OAEP,请传递一个
RsaOaepParams对象。 - 要使用 AES-CTR,请传递一个
AesCtrParams对象。 - 要使用 AES-CBC,请传递一个
AesCbcParams对象。 - 要使用 AES-GCM,请传递一个
AesGcmParams对象。
- 要使用 RSA-OAEP,请传递一个
key-
一个包含用于加密的密钥的
CryptoKey对象。 data-
一个
ArrayBuffer、一个TypedArray或一个DataView,其中包含要加密的数据(也称为 明文)。
返回值
一个 Promise,它将以一个包含“密文”的 ArrayBuffer 来fulfilled。
异常
当遇到以下异常时,Promise 将被 rejected
InvalidAccessErrorDOMException-
当提供的密钥不适用于请求的操作时(例如,无效的加密算法,或指定的加密算法的密钥无效)抛出。
OperationErrorDOMException-
当操作由于特定于操作的原因而失败时(例如,算法参数大小无效,或 AES-GCM 明文长度超过 239−256 字节)抛出。
支持的算法
Web Crypto API 提供了四种支持 encrypt() 和 decrypt() 操作的算法。
其中一种算法——RSA-OAEP——是公钥加密系统。
这里的另外三种加密算法都是对称算法,并且它们都基于相同的底层密码 AES(Advanced Encryption Standard)。它们之间的区别在于模式。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。Nonces 不必保密,但不能与同一密钥重复使用。
- 一个计数器。当加密每个块时,这个块部分会递增。
本质上:nonce 应确保计数器块不会在消息之间重复使用,而计数器应确保计数器块不会在单个消息内部重复使用。
注意: 有关更多信息,请参阅 NIST SP800-38A 标准的附录 B。
AES-CBC
这代表了密码块链接模式下的 AES,如 NIST SP800-38A 中所述。
AES-GCM
这代表了伽罗瓦/计数器模式下的 AES,如 NIST SP800-38D 中所述。
此模式与其他模式的一个主要区别是 GCM 是“认证”模式,这意味着它包含对密文未被攻击者修改的检查。
示例
注意: 您可以在 GitHub 上尝试工作示例。
RSA-OAEP
此代码获取文本框的内容,对其进行编码以进行加密,并使用 RSA-OAEP 进行加密。在 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 模式进行加密。在 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 = 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 上查看完整代码。
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 模式进行加密。在 GitHub 上查看完整代码。
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 }, key, encoded);
}
规范
| 规范 |
|---|
| Web 加密级别 2 # SubtleCrypto-method-encrypt |
浏览器兼容性
加载中…
另见
SubtleCrypto.decrypt().- RFC 3447 规定了 RSAOAEP。
- NIST SP800-38A 规定了 CTR 模式。
- NIST SP800-38A 规定了 CBC 模式。
- NIST SP800-38D 规定了 GCM 模式。