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
|
---
title: SubtleCrypto.deriveKey()
slug: Web/API/SubtleCrypto/deriveKey
tags:
- API
- Criptografía
- Crypto
- Referencia
- SubtleCrypto
- Web
- metodo
translation_of: Web/API/SubtleCrypto/deriveKey
---
<p>{{APIRef("Web Crypto API")}}</p>
<p>O método <code><strong>SubtleCrypto.deriveKey()</strong></code> retorna como {{jsxref("Promise")}} de um recentemente gerado {{domxref("CryptoKey")}} derivada de uma master key e um algoritmo específico dados como parâmetro.</p>
<h2 id="Sintaxe">Sintaxe</h2>
<pre class="syntaxbox">var <em>result</em> = crypto<code>.subtle.deriveKey(<em>algorithm</em>, <em>masterKey</em>, <em>derivedKeyAlgorithm</em>, <em>extractable</em>, <em>keyUsages</em>)</code>;
</pre>
<h3 id="Parâmetros">Parâmetros</h3>
<ul>
<li><code><em>algorithm</em></code> é um objeto definindo o algoritmo de derivação a se usar. Os valores suportados são:
<ul>
<li><code>{"name": "ECDH", "public": publicKey}</code></li>
<li><code>{"name": "DH", "public": publicKey}</code></li>
<li><code>{"name": "PBKDF2", salt, iterations, hash}</code> where <em><code>salt</code></em> is an {{jsxref("ArrayBuffer")}} ou um {{jsxref("ArrayBufferView")}}, <em><code>iterations</code></em> é o número de interações e <em><code>hash</code></em> é um {{domxref("DOMString")}} identificando o algoritmo hashing para uso.</li>
<li><code>{"name": "HKDF-CTR", hash, label, context}</code></li>
</ul>
</li>
<li><em><code>masterKey</code></em> é uma {{domxref("CryptoKey")}} representando a master key para ser utilizada por um algoritmo de derivação de key.</li>
<li><code><em>derivedKeyAlgorithm</em></code> é um objeto que define o algoritmo, a key derivada será utilizada para {{domxref("DOMString")}} como um atalho para <code>{"name": derivedKeyAlgo}</code>. Para AES uma propriedade <code><em>length</em></code> também é requerida, e os valores possíveis são 128, 192 ou 256 bits.</li>
<li><code><em>extractable</em></code> é um {{jsxref("Boolean")}} indicando se a key pode ser extraída de um objeto {{domxref("CryptoKey")}} em um estágio mais tardio.</li>
<li><code><em>keyUsages</em></code> é um {{jsxref("Array")}} indicando o que pode ser feito com a chave derivada. Os valores possíveis do array são:
<ul>
<li><code>"encrypt"</code>, permitindo que a key seja utilizada para {{glossary("encryption", "encrypting")}} mensagens.</li>
<li><code>"decrypt"</code>, permitindo que a key seja utilizada para {{glossary("decryption", "decrypting")}} mensagens.</li>
<li><code>"sign"</code>, permitindo que a key seja utilizada para {{glossary("signature", "signing")}} mensagens.</li>
<li><code>"verify"</code>, permitindo que a key seja utilizada para {{glossary("verification", "verifying the signature")}} de mensagens.</li>
<li><code>"deriveKey"</code>, permitindo que a key seja utilizada como key base na derivação de uma nova key.</li>
<li><code>"deriveBits"</code>, permitindo que a key seja utilizada como key base na derivação de bits de informação para uso em criptografias primitivas.</li>
<li><code>"wrapKey"</code>, permitindo que a key envolva uma key simétrica (transferência, armazenamento) em ambientes não seguros.</li>
<li><code>"unwrapKey"</code>, permitindo que a key se desvincule de uma key simétrica para uso (transfererência, armazenamento) em ambientes não seguros.</li>
</ul>
</li>
</ul>
<h3 id="Valor_de_retorno">Valor de retorno</h3>
<ul>
<li><code><em>result</em></code> é uma {{jsxref("Promise")}} que retorna a key derivada como uma {{domxref("CryptoKey")}} ou uma {{domxref("CryptoKeyPair")}}.</li>
</ul>
<h3 id="Exceções">Exceções</h3>
<p>A promise é rejeitada quando uma das seguintes exceções é encontrada:</p>
<ul>
<li>{{exception("InvalidAccessError")}} quando a master key não é uma key para o algoritmo de derivação requisitado ou se o valor desta chave, {{domxref("CryptoKey.usages")}}, não contém <code>"deriveKey"</code>.</li>
<li>{{exception("NotSupported")}} quando tentando usar um algoritmo que não é nem desconhecido e nem se encaixa para a derivação, ou se, o algoritmo requisitado da key derivada não define o comprimento da key.</li>
<li>{{exception("SyntaxError")}} quando <em><code>keyUsages</code></em> está vazio mas a key desvinculada é do tipo <code>"secret"</code> ou <code>"private"</code>.</li>
</ul>
<h2 id="Exemplo" style="font-size: 2.14285714285714rem;">Exemplo</h2>
<p style="line-height: 16.7999992370605px;">Aqui está um exemplo de como usar <strong>deriveKey()</strong> para criar uma <strong>Secure Remote Password</strong> (também nomeado de <strong>Proof of Secret</strong>) da password de um usuário.</p>
<pre class="brush: js" style="font-size: 14px;">// salt deve ser Uint8Array ou ArrayBuffer
var saltBuffer = Unibabel.hexToBuffer('e85c53e7f119d41fd7895cdc9d7bb9dd');
// não use métodos naïve para conversão de texto, senão caracteres
// internacionais não terão a sequência correta de byte. Use o TextEncoder quando
// possível ou então use polyfills relevantes
var passphraseKey = Unibabel.utf8ToBuffer("I hëart årt and £$¢!");
// Você deve primeiramente importar sua passphrase Uint8array em uma CryptoKey
window.crypto.subtle.importKey(
'raw',
passphraseKey,
{name: 'PBKDF2'},
false,
['deriveBits', 'deriveKey']
).then(function(key) {
return window.crypto.subtle.deriveKey(
{ "name": 'PBKDF2',
"salt": saltBuffer,
// não seja muito ambicioso, ou pelo menos tenha em mente
// que celulares com baixo poder de processamento vão acessar o seu app
"iterations": 100,
"hash": 'SHA-256'
},
key,
// Nota: para essa demo nós não vamos precisar de uma cipher suite,
// mas a API exige que a mesma seja especificada.
// Para AES o comprimento requerido é de 128 ou 256 bits (não bytes)
{ "name": 'AES-CBC', "length": 256 },
// Independente da resposta a key é extraível (menos seguro) ou não extraível (mais seguro),
// quando falso, a key pode ser entregue apenas como um objeto crypto web, não inspecionado
true,
// esse objeto crypto web será permitido para apenas essas funções:
[ "encrypt", "decrypt" ]
)
}).then(function (webKey) {
return crypto.subtle.exportKey("raw", webKey);
}).then(function (buffer) {
var proofOfSecret = Unibabel.bufferToHex(buffer);
// esta proof-of-secret / password remota-segura
// pode agora ser enviada no lugar da password do usuário
});</pre>
<p style="line-height: 16.7999992370605px;">Nota: Por conta de não haver ferramentas nativas que convertam entre Uint8Array, Unicode, hex, e base64, você provavelmente vai querer utilizar algo como o <a href="https://github.com/coolaj86/unibabel-js">Unibabel</a> ou <a href="https://github.com/feross/buffer">Buffer</a> para converter entre eles.</p>
<h2 id="Especificações">Especificações</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Especificação</th>
<th scope="col">Status</th>
<th scope="col">Comentário</th>
</tr>
<tr>
<td>{{ SpecName('Web Crypto API', '#dfn-SubtleCrypto-method-deriveKey', 'SubtleCrypto.deriveKey()') }}</td>
<td>{{ Spec2('Web Crypto API') }}</td>
<td>Definição inicial.</td>
</tr>
</tbody>
</table>
<h2 id="Compatibilidade_de_Browser">Compatibilidade de Browser</h2>
<p>{{ CompatibilityTable() }}</p>
<div id="compat-desktop">
<table class="compat-table">
<tbody>
<tr>
<th>Característica</th>
<th>Chrome</th>
<th>Edge</th>
<th>Firefox (Gecko)</th>
<th>Internet Explorer</th>
<th>Opera</th>
<th>Safari</th>
</tr>
<tr>
<td>Suporte básico</td>
<td>{{ CompatChrome(37) }}</td>
<td>{{CompatVersionUnknown}}</td>
<td>{{ CompatGeckoDesktop(34) }}</td>
<td>{{ CompatNo() }}</td>
<td>{{ CompatUnknown() }}</td>
<td>{{ CompatSafari(11) }}</td>
</tr>
<tr>
<td><code>PBKDF2</code></td>
<td>{{ CompatChrome(42) }}</td>
<td>{{CompatUnknown}}</td>
<td>{{ CompatGeckoDesktop(34) }}</td>
<td>{{ CompatNo() }}</td>
<td>{{ CompatUnknown() }}</td>
<td>{{ CompatSafari(11) }}</td>
</tr>
<tr>
<td><code>HKDF-CTR</code></td>
<td>{{ CompatChrome(42) }}</td>
<td>{{ CompatNo() }}</td>
<td>{{ CompatNo() }}</td>
<td>{{ CompatNo() }}</td>
<td>{{ CompatNo() }}</td>
<td>{{ CompatUnknown() }}</td>
</tr>
<tr>
<td><code>DH</code></td>
<td>{{ CompatNo() }}</td>
<td>{{CompatUnknown}}</td>
<td>{{ CompatGeckoDesktop(35) }}</td>
<td>{{ CompatNo() }}</td>
<td>{{ CompatNo() }}</td>
<td>{{ CompatUnknown() }}</td>
</tr>
</tbody>
</table>
</div>
<div id="compat-mobile">
<table class="compat-table">
<tbody>
<tr>
<th>Característica</th>
<th>Android</th>
<th>Edge</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>Suporte básico</td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatVersionUnknown}}</td>
<td>37</td>
<td>{{ CompatGeckoMobile(34) }}</td>
<td>{{ CompatNo }}</td>
<td>{{ CompatUnknown() }}</td>
<td>{{ CompatNo }}</td>
</tr>
<tr>
<td><code>PBKDF2</code></td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatUnknown}}</td>
<td>42</td>
<td>{{ CompatGeckoMobile(34) }}</td>
<td>{{ CompatNo }}</td>
<td>{{ CompatUnknown() }}</td>
<td>{{ CompatNo }}</td>
</tr>
<tr>
<td><code>HKDF-CTR</code></td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatUnknown}}</td>
<td>42</td>
<td>{{ CompatNo() }}</td>
<td>{{ CompatNo() }}</td>
<td>{{ CompatNo() }}</td>
<td>{{ CompatNo() }}</td>
</tr>
<tr>
<td><code>DH</code></td>
<td>{{ CompatNo() }}</td>
<td>{{CompatUnknown}}</td>
<td>{{ CompatNo() }}</td>
<td>{{ CompatGeckoMobile(35) }}</td>
<td>{{ CompatNo() }}</td>
<td>{{ CompatNo() }}</td>
<td>{{ CompatNo() }}</td>
</tr>
</tbody>
</table>
</div>
<h2 id="Veja_também">Veja também</h2>
<ul>
<li>{{domxref("Crypto")}} e {{domxref("Crypto.subtle")}}.</li>
<li>{{domxref("SubtleCrypto")}}, a interface a qual ele pertence.</li>
</ul>
<h3 id="Dicionário">Dicionário:</h3>
<p>"Key" = "Chave"</p>
<p>"Master key" = "Chave mestre"</p>
<p>"Proof-of-secret" = "Prova de segredo ou Atestado de sigilo"</p>
<p>"Password" = "Palavra passe ou Senha"</p>
|