From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- .../zh-cn/web/api/subtlecrypto/decrypt/index.html | 94 ++++++ .../zh-cn/web/api/subtlecrypto/encrypt/index.html | 249 +++++++++++++++ files/zh-cn/web/api/subtlecrypto/index.html | 334 +++++++++++++++++++++ 3 files changed, 677 insertions(+) create mode 100644 files/zh-cn/web/api/subtlecrypto/decrypt/index.html create mode 100644 files/zh-cn/web/api/subtlecrypto/encrypt/index.html create mode 100644 files/zh-cn/web/api/subtlecrypto/index.html (limited to 'files/zh-cn/web/api/subtlecrypto') diff --git a/files/zh-cn/web/api/subtlecrypto/decrypt/index.html b/files/zh-cn/web/api/subtlecrypto/decrypt/index.html new file mode 100644 index 0000000000..2f303bda6c --- /dev/null +++ b/files/zh-cn/web/api/subtlecrypto/decrypt/index.html @@ -0,0 +1,94 @@ +--- +title: SubtleCrypto.decrypt() +slug: Web/API/SubtleCrypto/decrypt +translation_of: Web/API/SubtleCrypto/decrypt +--- +

{{APIRef("Web Crypto API")}}

+ +

SubtleCrypto.decrypt() 以加密数据、算法和密钥为参数返回一个包含明文的 {{jsxref("Promise")}} 对象。

+ +

语法

+ +
var result = crypto.subtle.decrypt(algorithm, key, data);
+
+ +

属性

+ + + +

返回值

+ + + +

异常

+ +

Promise 将会在以下的异常被触发时返回 rejected:

+ +
+
InvalidAccessError
+
当提供的密钥无法执行请求的操作时(如:解密算法无效,或对指定的解密算法提供了无效的密钥)。
+
OperationError
+
因特定的操作原因导致操作失败时(如:算法的参数大小无效,或解密结果失败)。
+
+ +

实例

+ +
const decryptText = async (ctBuffer, iv, password) => {
+    const pwUtf8 = new TextEncoder().encode(password);
+    const pwHash = await crypto.subtle.digest('SHA-256', pwUtf8);
+
+    const alg = { name: 'AES-GCM', iv: iv };
+    const key = await crypto.subtle.importKey('raw', pwHash, alg, false, ['decrypt']);
+
+    const ptBuffer = await crypto.subtle.decrypt(alg, key, ctBuffer);
+
+    const plaintext = new TextDecoder().decode(ptBuffer);
+
+    return plaintext;
+}
+ +

iv 的含义在 {{domxref("SubtleCrypto.encrypt()")}} 中可以找到。ctBuffer 是 {{domxref("SubtleCrypto.encrypt()")}} 返回的密文。

+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{ SpecName('Web Crypto API', '#SubtleCrypto-method-decrypt', 'SubtleCrypto.decrypt()') }}{{ Spec2('Web Crypto API') }}Initial definition.
+ +

浏览器支持

+ + + +

{{Compat("api.SubtleCrypto.decrypt")}}

+ +

另请参见

+ + diff --git a/files/zh-cn/web/api/subtlecrypto/encrypt/index.html b/files/zh-cn/web/api/subtlecrypto/encrypt/index.html new file mode 100644 index 0000000000..a135fe54ff --- /dev/null +++ b/files/zh-cn/web/api/subtlecrypto/encrypt/index.html @@ -0,0 +1,249 @@ +--- +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);
+
+ +

参数

+ + + +

返回值

+ + + +

异常

+ +

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

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

支持的算法

+ +

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

+ +

关于 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
{{ SpecName('Web Crypto API', '#dfn-SubtleCrypto-method-encrypt', 'SubtleCrypto.encrypt()') }}{{ Spec2('Web Crypto API') }}Initial definition.
+ +

浏览器兼容性

+ + + +

{{Compat("api.SubtleCrypto.encrypt")}}

+ +

另见

+ + diff --git a/files/zh-cn/web/api/subtlecrypto/index.html b/files/zh-cn/web/api/subtlecrypto/index.html new file mode 100644 index 0000000000..24dec9a283 --- /dev/null +++ b/files/zh-cn/web/api/subtlecrypto/index.html @@ -0,0 +1,334 @@ +--- +title: SubtleCrypto +slug: Web/API/SubtleCrypto +tags: + - 加密 +translation_of: Web/API/SubtleCrypto +--- +

{{APIRef("Web Crypto API")}}

+ +

基于Web Crypto APISubtleCrypto 接口提供了许多底层加密功能。它通过窗口上下文提供可用的{{domxref("Crypto.subtle")}} 属性来访问(通过{{domxref("Window.crypto")}})。

+ +
+

注意: 此API提供了许多底层加密源语。滥用他们很容易陷入微妙的陷阱中。

+ +

即使你正确的使用基础加密方法,也很难设计一套正确的安全密钥管理及整体安全设计方案,这些往往是安全专家的领域。

+ +

错误的安全系统设计和实现会使系统的安全性完全失效

+ +

如果你不知道此API能为你提供什么,则不应该使用该API

+
+ +

概览

+ +

我们可以将此API的功能分为两类:加密功能和密钥管理功能。

+ +

加密功能

+ +

这些函数你可以用来实现系统中的隐私和身份验证等安全功能。SubtleCrypto API提供了如下加密函数:

+ +

sign() 、 verify(): 创建和验证数字签名。
+ * encrypt() and decrypt(): 加密和解密数据。
+ * digest(): create a fixed-length, collision-resistant digest of some data.

+ +

密钥管理功能

+ +

除了 digest(),在SubtleCrypto API中所有加密功能都会使用密钥,并使用CryptoKey对象表示加密密钥。要执行签名和加密操作, 请将 CryptoKey 对象传参给 sign() 或 encrypt() 函数.

+ +

生成和派生密钥

+ +

generateKey() 和 deriveKey() 函数都可以创建一个新的 CryptoKey 对象。

+ +

不同之处在于 generateKey() 每次都会生成一个新的键值对, 而 deriveKey() 通过从基础密钥资源中生成一个新的密钥。如果为两个独立的deriveKey()提供相同的基础密钥资源,那么你会获得两个具有相同基础值的 CryptoKey 对象。如果你想通过密码派生加密密钥,然后从相同的密码派生相同的密钥以解密数据,那么这将会非常有用。

+ +

导入和导出密钥

+ +

要在应用程序外部使密钥可用,您需要导出密钥,exportKey() 可以为你提供该功能。你可以选择多种导出格式。

+ +

importKey()与 exportKey() 刚好相反。你可以从其他系统导入密钥,并且支持像 PKCS #8 和 JSON Web Key 这样可以帮助你执行此操作的标准格式。exportKey() 函数以非标准格式导出密钥。

+ +

如果密钥是敏感的,你需要使用 wrapKey(), 该函数导出密钥并且使用另外一个密钥加密它。

+ +

unwrapKey()wrapKey()相反,该函数解密密钥后导入解密的密钥

+ +

存储密钥

+ +

CryptoKey对象可以通过 structured clone algorithm来存储,这意味着你可以通过web storage APIs来存储和获取他们。更为规范的方式是通过使用IndexedDB API 来存储CryptoKey对象。

+ +

支持的算法

+ +

Web Crypto API提供的加密函数可以由一个或多个不同的加密算法执行:

+ +

函数可以通过参数来指定使用的算法。一些算法需要额外的参数,在这些情况下通过将算法参数作为对象字典传入额外的参数中实现。

+ +

下表总结了哪些算法适用于哪些加密操作:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  +

sign()

+ +

verify()

+
+

encrypt()

+ +

decrypt()

+
digest() +

deriveBits()

+ +

deriveKey()

+
+

wrapKey()

+ +

unwrapKey()

+
RSASSA-PKCS1-v1_5    
RSA-PSS    
ECDSA    
HMAC    
RSA-OAEP   
AES-CTR   
AES-CBC   
AES-GCM   
SHA-1    
SHA-256    
SHA-384    
SHA-512    
ECDH    
HKDF    
PBKDF2    
AES-KW    
+ +

属性

+ +

此接口既不继承也不实现任何属性。

+ +

方法

+ +

此接口不继承任何方法。

+ +
+
{{domxref("SubtleCrypto.encrypt()")}}
+
以算法、密钥、明文为参数,返回一个包含加密数据的 {{jsxref("Promise")}}对象。
+
{{domxref("SubtleCrypto.decrypt()")}}
+
以算法、密钥、明文为参数,返回一个包含解密数据的 {{jsxref("Promise")}}对象。
+
{{domxref("SubtleCrypto.sign()")}}
+
以文本、算法和密码为参数,返回一个包含签名的 {{jsxref("Promise")}}。
+
{{domxref("SubtleCrypto.verify()")}}
+
以签名、与之匹配的文本、算法、密码为参数,验证签名的真实性,返回一个包含布尔型的 {jsxref("Promise")}} 对象。
+
{{domxref("SubtleCrypto.digest()")}}
+
以生成摘要的算法和文本作为参数,返回一个包含数据摘要的 {{jsxref("Promise")}} 对象。
+
{{domxref("SubtleCrypto.generateKey()")}}
+
以给出的用法和返可提取性作为参数,返回一个包含用于对称算法的新生成的 {{domxref("CryptoKey")}} 或者包含两个新的生成的密钥用于非对称加密的 {{domxref("CryptoKeyPair")}} 的 {{jsxref("Promise")}} 对象。
+
{{domxref("SubtleCrypto.deriveKey()")}}
+
以从 master key 派生出来的密钥和特定的算法作为参数,返回一个包含新生成的 {{domxref("CryptoKey")}}  的 {{jsxref("Promise")}}对象。
+
{{domxref("SubtleCrypto.deriveBits()")}}
+
以从 master key 派生出来的密钥和特定的算法作为参数,返回一个包含新生成的伪随机字节的 Buffer的 {{jsxref("Promise")}} 对象。
+
{{domxref("SubtleCrypto.importKey()")}}
+
以格式、算法、原始密钥数据、用途和可提取性作为参数,返回一个包含 {{domxref("CryptoKey")}} 的 {{jsxref("Promise")}} 对象。
+
{{domxref("SubtleCrypto.exportKey()")}}
+
返回一个包含所请求格式的密钥的 Buffer 的 {{jsxref("Promise")}} 对象。
+
{{domxref("SubtleCrypto.wrapKey()")}}
+
返回一个包含在不安全环境中使用(传输,存储)的包裹对称密钥的 {{jsxref("Promise")}} 对象。返回的被包裹的缓冲数据是按照参数中给出的格式的,包含使用给定算法的给予包装密钥包裹的密钥。
+
{{domxref("SubtleCrypto.unwrapKey()")}}
+
返回一个包含对应于参数中给出的包裹密钥的 {{domxref("CryptoKey")}} 的 {{jsxref("Promise")}} 对象。
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{ SpecName('Web Crypto API', '#subtlecrypto-interface', 'SubtleCrypto') }}{{ Spec2('Web Crypto API') }}Initial definition.
+ +

浏览器支持

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatChrome(37) }}{{ CompatGeckoDesktop(34) }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatNo }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support37{{ CompatChrome(37) }}{{ CompatGeckoMobile(34) }}{{ CompatNo }}{{ CompatUnknown() }}{{ CompatNo }}
+
+ +

另见

+ + -- cgit v1.2.3-54-g00ecf