# SubtleCrypto

A interface `SubtleCrypto` reúne as funções criptográficas de baixo nível da Web Crypto API no Azion Runtime. Uma function a acessa pela propriedade `subtle` do objeto global [`crypto`](/pt-br/documentacao/devtools/runtime/api-reference/crypto/). Essa propriedade contém uma instância de `SubtleCrypto`. Use-a para gerar hashes de dados, assinar e verificar mensagens, criptografar e descriptografar dados e derivar, importar, exportar e encapsular chaves. Para mais informações, consulte [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto) na MDN Web Docs.

---

## Métodos

`SubtleCrypto` não tem interface pai, então não herda métodos. Todo método retorna uma promise:

| Método                                                                                                                                                                                                  | Descrição                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`crypto.subtle.encrypt(algorithm, key, data)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/encrypt)                                                                                  | Resolve com a forma criptografada de `data`, produzida com `key` e `algorithm`. `AES-GCM` criptografa com uma chave de 256 bits e um `iv`.                                                                                                                                                                                                                                        |
| [`crypto.subtle.decrypt(algorithm, key, data)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/decrypt)                                                                                  | Resolve com os dados em claro recuperados de `data` criptografado, usando `key` e `algorithm`.                                                                                                                                                                                                                                                                                    |
| [`crypto.subtle.sign(algorithm, key, data)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/sign)                                                                                        | Resolve com a assinatura de `data`, calculada com `key` e `algorithm`. `HMAC`, `ECDSA`, `RSA-PSS` e `Ed25519` assinam dados. Uma assinatura `RSA-PSS` com uma chave de 2048 bits tem 256 bytes. Uma assinatura `Ed25519` tem 64 bytes.                                                                                                                                            |
| [`crypto.subtle.verify(algorithm, key, signature, data)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/verify)                                                                         | Resolve com `true` quando `signature` corresponde a `data` com `key` e `algorithm`, e com `false` quando não corresponde, por exemplo depois que `data` muda.                                                                                                                                                                                                                     |
| [`crypto.subtle.digest(algorithm, data)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest)                                                                                         | Resolve com o digest de `data` calculado com `algorithm`. `SHA-1`, `SHA-256`, `SHA-384` e `SHA-512` produzem 20, 32, 48 e 64 bytes. `MD5` rejeita com `NotSupportedError: Unrecognized algorithm name`.                                                                                                                                                                           |
| [`crypto.subtle.generateKey(algorithm, extractable, keyUsages)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey)                                                             | Resolve com uma [`CryptoKey`](/pt-br/documentacao/devtools/runtime/api-reference/crypto-key/) para um algoritmo simétrico ou com um `CryptoKeyPair` com `privateKey` e `publicKey` para um algoritmo assimétrico. As chaves recebem o algoritmo, os usos e a extraibilidade que você passa. Ele gera chaves `AES-GCM`, `AES-KW`, `ECDSA` na curva `P-256`, `RSA-PSS` e `Ed25519`. |
| [`crypto.subtle.deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey)                                   | Resolve com uma `CryptoKey` derivada de `baseKey` com `algorithm`. `PBKDF2` com `SHA-256` deriva uma chave `AES-GCM` de 256 bits.                                                                                                                                                                                                                                                 |
| [`crypto.subtle.deriveBits(algorithm, baseKey, length)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveBits)                                                                      | Resolve com um buffer de bits pseudoaleatórios derivados de `baseKey` com `algorithm`. `length` é o número de bits.                                                                                                                                                                                                                                                               |
| [`crypto.subtle.importKey(format, keyData, algorithm, extractable, keyUsages)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey)                                                | Resolve com uma `CryptoKey` construída a partir de `keyData` em `format`. A chave recebe o algoritmo, os usos e a extraibilidade que você passa. Ele importa uma chave `raw` para `HMAC` ou `PBKDF2`.                                                                                                                                                                             |
| [`crypto.subtle.exportKey(format, key)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)                                                                                       | Resolve com os dados da chave `key` em `format`, como `raw` ou `jwk`. `exportKey()` rejeita uma chave criada com `extractable` definido como `false`, com `InvalidAccessError: Key is not extractable`.                                                                                                                                                                           |
| [`crypto.subtle.wrapKey(format, key, wrappingKey, wrapAlgorithm)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/wrapKey)                                                               | Resolve com `key` exportada em `format` e criptografada com `wrappingKey` e `wrapAlgorithm`. Use-o para transferir ou armazenar uma chave simétrica em um ambiente não confiável. Uma chave `AES-GCM` de 256 bits encapsulada no formato `raw` com `AES-KW` tem 40 bytes.                                                                                                         |
| [`crypto.subtle.unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/unwrapKey) | Resolve com a `CryptoKey` que `wrappedKey` contém, descriptografada com `unwrappingKey` e `unwrapAlgorithm`.                                                                                                                                                                                                                                                                      |

---

## Exemplo

Este handler importa um segredo como uma chave `HMAC`, assina uma mensagem e verifica a assinatura com a mensagem e com dados alterados. Ele retorna a assinatura, os dois resultados e as propriedades da chave com `Response.json()`:

```javascript
export default {
  async fetch(request, env, ctx) {
    const encoder = new TextEncoder();
    const hex = (buffer) =>
      Array.from(new Uint8Array(buffer), (byte) => byte.toString(16).padStart(2, '0')).join('');

    const key = await crypto.subtle.importKey(
      'raw',
      encoder.encode('a secret'),
      { name: 'HMAC', hash: 'SHA-256' },
      false,
      ['sign', 'verify'],
    );
    const signature = await crypto.subtle.sign('HMAC', key, encoder.encode('Azion Functions'));
    const verifies = await crypto.subtle.verify('HMAC', key, signature, encoder.encode('Azion Functions'));
    const tampered = await crypto.subtle.verify('HMAC', key, signature, encoder.encode('tampered'));

    return Response.json({
      signatureHex: hex(signature),
      verifies,
      rejectsTampered: !tampered,
      key: {
        type: key.type,
        extractable: key.extractable,
        algorithm: key.algorithm,
        usages: key.usages,
        ctor: key.constructor.name,
      },
    });
  },
};
```

A function retorna estes valores. `rejectsTampered` é `true` porque `verify()` retorna `false` para os dados alterados:

```json
{
 "signatureHex": "86fec9e22ad82998c7007d637f61a5206e2b64ee2a8ac2ed12f1f359e3d14bc6",
 "verifies": true,
 "rejectsTampered": true,
 "key": {
  "type": "secret",
  "extractable": false,
  "algorithm": {
   "name": "HMAC",
   "length": 64,
   "hash": {
    "name": "SHA-256"
   }
  },
  "usages": [
   "sign",
   "verify"
  ],
  "ctor": "CryptoKey"
 }
}
```

---

## Recursos relacionados

- [Crypto](/pt-br/documentacao/devtools/runtime/api-reference/crypto.md): O objeto global `crypto`, os valores aleatórios dele e a propriedade `subtle`.
- [CryptoKey](/pt-br/documentacao/devtools/runtime/api-reference/crypto-key.md): O objeto de chave que os métodos de `SubtleCrypto` criam e aceitam.
- [node:crypto](/pt-br/documentacao/devtools/runtime/node/crypto.md): O módulo crypto do Node.js que o Azion Runtime oferece por meio de polyfills.
- [Web APIs](/pt-br/documentacao/devtools/runtime/api-reference/javascript.md): As outras Web APIs que o Azion Runtime suporta.
