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 模式。