aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/api/subtlecrypto/index.html
blob: c173e906e8d819157ee6ed56d41863944264add5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
---
title: SubtleCrypto
slug: Web/API/SubtleCrypto
tags:
  - 加密
translation_of: Web/API/SubtleCrypto
---
<p>{{APIRef("Web Crypto API")}}</p>

<p>基于<a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API">Web Crypto API</a><strong>SubtleCrypto</strong> 接口提供了许多底层加密功能。它通过窗口上下文提供可用的{{domxref("Crypto.subtle")}} 属性来访问(通过{{domxref("Window.crypto")}})。</p>

<div class="warning">
<p>注意: 此API提供了许多底层加密源语。滥用他们很容易陷入微妙的陷阱中。</p>

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

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

<p><strong>如果你不知道此API能为你提供什么,则不应该使用该API</strong></p>
</div>

<h2 id="概览">概览</h2>

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

<h3 id="加密功能">加密功能</h3>

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

<p><code><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/sign">sign()</a></code> 、 <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/verify">verify()</a></code>: 创建和验证数字签名。<br>
 * <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/encrypt">encrypt()</a></code><code><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/decrypt">decrypt()</a></code>: 加密和解密数据。<br>
 * <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest">digest()</a></code>:为数据生成一个定长的,防碰撞的消息摘要。</p>

<h3 id="密钥管理功能">密钥管理功能</h3>

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

<h4 id="生成和派生密钥"><strong>生成和派生密钥</strong></h4>

<p><code><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey">generateKey()</a></code> 和 <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey">deriveKey()</a></code> 函数都可以创建一个新的 <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey">CryptoKey</a></code> 对象。</p>

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

<h4 id="导入和导出密钥">导入和导出密钥</h4>

<p>要在应用程序外部使密钥可用,您需要导出密钥,<code><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey">exportKey()</a> </code>可以为你提供该功能。你可以选择多种导出格式。</p>

<p><code><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey">importKey()</a></code>与 <code>exportKey()</code> 刚好相反。你可以从其他系统导入密钥,并且支持像 <a href="https://tools.ietf.org/html/rfc5208">PKCS #8</a> 和 <a href="https://tools.ietf.org/html/rfc7517">JSON Web Key</a> 这样可以帮助你执行此操作的标准格式。<code>exportKey()</code> 函数以非标准格式导出密钥。</p>

<p>如果密钥是敏感的,你需要使用 <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/wrapKey">wrapKey()</a></code>, 该函数导出密钥并且使用另外一个密钥加密它。</p>

<p><code><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/unwrapKey">unwrapKey()</a><font face="Arial, x-locale-body, sans-serif"><span style="background-color: #ffffff;"></span></font></code><code>wrapKey()</code>相反,该函数解密密钥后导入解密的密钥</p>

<h4 id="存储密钥">存储密钥</h4>

<p><code>CryptoKey</code>对象可以通过 <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm">structured clone algorithm</a></code>来存储,这意味着你可以通过web storage APIs来存储和获取他们。更为规范的方式是通过使用<code><a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API">IndexedDB API</a></code> 来存储<code>CryptoKey</code>对象。</p>

<h3 id="支持的算法">支持的算法</h3>

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

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

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

<table>
 <thead>
  <tr>
   <th scope="row"> </th>
   <th scope="col">
    <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/sign">sign()</a></p>

    <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/verify">verify()</a></p>
   </th>
   <th scope="col">
    <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/encrypt">encrypt()</a></p>

    <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/decrypt">decrypt()</a></p>
   </th>
   <th scope="col"><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest">digest()</a></th>
   <th scope="col">
    <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveBits">deriveBits()</a></p>

    <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey">deriveKey()</a></p>
   </th>
   <th scope="col">
    <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/wrapKey">wrapKey()</a></p>

    <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/unwrapKey">unwrapKey()</a></p>
   </th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <th scope="row">RSASSA-PKCS1-v1_5</th>
   <td></td>
   <td> </td>
   <td> </td>
   <td> </td>
   <td> </td>
  </tr>
  <tr>
   <th scope="row">RSA-PSS</th>
   <td></td>
   <td> </td>
   <td> </td>
   <td> </td>
   <td> </td>
  </tr>
  <tr>
   <th scope="row">ECDSA</th>
   <td></td>
   <td> </td>
   <td> </td>
   <td> </td>
   <td> </td>
  </tr>
  <tr>
   <th scope="row">HMAC</th>
   <td></td>
   <td> </td>
   <td> </td>
   <td> </td>
   <td> </td>
  </tr>
  <tr>
   <th scope="row">RSA-OAEP</th>
   <td> </td>
   <td></td>
   <td> </td>
   <td> </td>
   <td></td>
  </tr>
  <tr>
   <th scope="row">AES-CTR</th>
   <td> </td>
   <td></td>
   <td> </td>
   <td> </td>
   <td></td>
  </tr>
  <tr>
   <th scope="row">AES-CBC</th>
   <td> </td>
   <td></td>
   <td> </td>
   <td> </td>
   <td></td>
  </tr>
  <tr>
   <th scope="row">AES-GCM</th>
   <td> </td>
   <td></td>
   <td> </td>
   <td> </td>
   <td></td>
  </tr>
  <tr>
   <th scope="row">SHA-1</th>
   <td> </td>
   <td> </td>
   <td></td>
   <td> </td>
   <td> </td>
  </tr>
  <tr>
   <th scope="row">SHA-256</th>
   <td> </td>
   <td> </td>
   <td></td>
   <td> </td>
   <td> </td>
  </tr>
  <tr>
   <th scope="row">SHA-384</th>
   <td> </td>
   <td> </td>
   <td></td>
   <td> </td>
   <td> </td>
  </tr>
  <tr>
   <th scope="row">SHA-512</th>
   <td> </td>
   <td> </td>
   <td></td>
   <td> </td>
   <td> </td>
  </tr>
  <tr>
   <th scope="row">ECDH</th>
   <td> </td>
   <td> </td>
   <td> </td>
   <td></td>
   <td> </td>
  </tr>
  <tr>
   <th scope="row">HKDF</th>
   <td> </td>
   <td> </td>
   <td> </td>
   <td></td>
   <td> </td>
  </tr>
  <tr>
   <th scope="row">PBKDF2</th>
   <td> </td>
   <td> </td>
   <td> </td>
   <td></td>
   <td> </td>
  </tr>
  <tr>
   <th scope="row">AES-KW</th>
   <td> </td>
   <td> </td>
   <td> </td>
   <td> </td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="属性">属性</h2>

<p><em>此接口既不继承也不实现任何属性。</em></p>

<h2 id="方法">方法</h2>

<p><em>此接口不继承任何方法。</em></p>

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

<h2 id="规范">规范</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{ SpecName('Web Crypto API', '#subtlecrypto-interface', 'SubtleCrypto') }}</td>
   <td>{{ Spec2('Web Crypto API') }}</td>
   <td>Initial definition.</td>
  </tr>
 </tbody>
</table>

<h2 id="浏览器支持">浏览器支持</h2>

<p>{{ CompatibilityTable() }}</p>

<div id="compat-desktop">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Chrome</th>
   <th>Firefox (Gecko)</th>
   <th>Internet Explorer</th>
   <th>Opera</th>
   <th>Safari</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{ CompatChrome(37) }}</td>
   <td>{{ CompatGeckoDesktop(34) }}</td>
   <td>{{ CompatNo() }}</td>
   <td>{{ CompatUnknown() }}</td>
   <td>{{ CompatNo }}</td>
  </tr>
 </tbody>
</table>
</div>

<div id="compat-mobile">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Android</th>
   <th>Chrome for Android</th>
   <th>Firefox Mobile (Gecko)</th>
   <th>IE Mobile</th>
   <th>Opera Mobile</th>
   <th>Safari Mobile</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>37</td>
   <td>{{ CompatChrome(37) }}</td>
   <td>{{ CompatGeckoMobile(34) }}</td>
   <td>{{ CompatNo }}</td>
   <td>{{ CompatUnknown() }}</td>
   <td>{{ CompatNo }}</td>
  </tr>
 </tbody>
</table>
</div>

<h2 id="另见">另见</h2>

<ul>
 <li>{{domxref("Crypto")}}{{domxref("Crypto.subtle")}}.</li>
 <li><a href="https://www.crypto101.io/">Crypto 101</a>: an introductory course on cryptography.</li>
</ul>