--- title: SubtleCrypto.encrypt() slug: Web/API/SubtleCrypto/encrypt tags: - API - Crypto - 加密 translation_of: Web/API/SubtleCrypto/encrypt ---
{{APIRef("Web Crypto API")}}
SubtleCrypto.encrypt() 方法以算法、密钥、明文为参数返回一个包含加密数据的 {{jsxref("Promise")}} 对象。
var result = crypto.encrypt(algo, key, cleartext);
algo 是一个使用加密函数的对象或者 {{domxref("DOMString")}},后者是 {"name": algo} 的缩写。支持的值是:
{"name": "AES-CBC", iv} iv 是具有16个随机字节的 {{jsxref("ArrayBuffer")}} 或 {{jsxref("ArrayBufferView")}} (这些应该由 {{domxref("RandomSource.getRandomValues()")}} 生成)。{"name": "AES-CTR", counter, length}{"name": "AES-GCM", iv, additionalData, tagLength} (additionalData 和 tagLength 是可选的){"name": "RSA-OAEP", label} (label 是可选的)key 是一个包含签名密钥的 {{domxref("CryptoKey")}}。cleartext 是一个包含需要加密的明文 {{jsxref("ArrayBuffer")}} 或者 {{jsxref("ArrayBufferView")}} 对象。当遇到以下异常时,promise 将会返回一次错误(reject):
Crypto 接口提供了支持 encrypt() 和 decrypt() 操作的四种算法。
其中的 RSA-OAEP 算法是一种非对称加密的公钥密码({{Glossary("public-key cryptography", "public-key cryptosystem")}})。
其它三种算法则都是对称密钥加密({{Glossary("Symmetric-key cryptography", "symmetric algorithms")}}),并且它们都是基于同一种基础加密,即 AES (Advanced Encryption Standard)。它们不同之处在于分组加密的操作方式({{Glossary("Block cipher mode of operation", "mode")}})。Crypto 接口支持以下三种 AES 加密类型:
这里强烈建议使用认证加密(authenticated encryption),它可以检测密文是否已被攻击者篡改。使用认证也可以避免选择密文攻击(chosen-ciphertext attacks),即攻击者可以请求系统解密任意的消息,然后使用解密结果来倒推出关于密钥的一些信息。虽然 CTR 和 CBC 模式可以添加认证,但是它们默认不提供该操作,并且在手动实现它们的时候,很同意犯一些微小但严重的错误。GCM 不支持内置的认证,由于这个原因,常常推荐使用另外两种 AES 加密算法。
关于 RSA-OAEP 公钥加密算法的规范位于 RFC 3447。
使用 Counter 模式的 AES 算法,相关规范位于 NIST SP800-38A。
使用 Cipher Block Chaining 模式的 AES 算法,规范位于NIST SP800-38A。
使用 Galois/Counter 模式的 AES 算法,规范位于 NIST SP800-38D。
这种模式与上面的模式不同之处在于,GCM 是一种 "认证(authenticated)" 模式,意思就是它包含了检测密文是否未被攻击者篡改的功能。
注意: 你可以在 GitHub 尝试这个示例(try the working examples)。
以下代码获取文本框中的内容,编码后进行加密,使用的算法为 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 模式加密,完整代码: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 模式加密,完整代码: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 模式加密,完整代码: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
);
}
| Specification | Status | Comment |
|---|---|---|
| {{ SpecName('Web Crypto API', '#dfn-SubtleCrypto-method-encrypt', 'SubtleCrypto.encrypt()') }} | {{ Spec2('Web Crypto API') }} | Initial definition. |
{{Compat("api.SubtleCrypto.encrypt")}}