> ## Documentation Index
> Fetch the complete documentation index at: https://docs.basaltic.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Criptografia de envelope

> O que é uma chave de dados, por que criptografar diretamente é o padrão errado e como o contexto de criptografia vincula um texto cifrado ao seu propósito.

<a id="envelope-encryption" />

## Criptografia de envelope

<Note>
  **Operações criptográficas são apenas API.** Criptografar, descriptografar, gerar chave de dados, assinar e verificar não têm controles de console. O console cria chaves, as inspeciona e as desliga; as operações que *usam* uma chave são executadas a partir de sua aplicação, ao lado do texto sem formatação no qual elas atuam.
</Note>

`POST /v1/keys/{key_id}/encrypt` envia seu texto simples para o KMS e recebe o texto cifrado de volta. Isso é bom para algo pequeno e raro — um valor de configuração, um token de API. É a forma errada para qualquer outra coisa, porque cada byte atravessa a rede duas vezes e cada operação custa uma viagem de ida e volta.

A alternativa é uma **chave de dados**: o KMS cria uma chave aleatória nova, entrega duas cópias dela e nunca a armazena.

<Tabs>
  <Tab title="API">
    ```bash theme={null}
    POST /v1/keys/{key_id}/generate-data-key
    { "number_of_bytes": 32 }
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic kms key generate-data-key <key-id> --number-of-bytes 32
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    dk, err := kms.New(cfg).GenerateDataKey(ctx, keyID, &kms.GenerateDataKeyRequest{
        NumberOfBytes: basaltic.Int(32),
    })
    ```

    `dk.Plaintext` é a chave a ser usada e depois descartada; `dk.Ciphertext` é a cópia a ser armazenada ao lado do que você criptografou.
  </Tab>
</Tabs>

```json theme={null}
{
  "plaintext":  "<base64 — the raw key bytes>",
  "ciphertext": "<base64 — the same key, wrapped under your KMS key>"
}
```

Você criptografa seus dados localmente com `plaintext`, então joga `plaintext` fora e armazena `ciphertext` ao lado dos dados que ele protege. Para ler os dados de volta, envie `ciphertext` para `POST /v1/keys/{key_id}/decrypt` e você terá a chave de dados novamente.

```mermaid theme={null}
sequenceDiagram
    participant App as Your application
    participant KMS
    participant Store as Your storage
    App->>KMS: generate-data-key
    KMS-->>App: plaintext + ciphertext
    App->>App: encrypt data with plaintext, then discard it
    App->>Store: store ciphertext beside the encrypted data
    Note over App,Store: later, on read
    Store-->>App: encrypted data + ciphertext
    App->>KMS: decrypt(ciphertext)
    KMS-->>App: plaintext data key
    App->>App: decrypt data locally
```

Seus dados em massa nunca saem do processo, uma chamada KMS cobre um lote inteiro e a chave KMS permanece uma chave de *criptografia de chave* — a única coisa que ela envolve são outras chaves.

<Warning>
  Nunca persistir a chave de dados `plaintext`. Armazená-lo ao lado de `ciphertext` derrota todo o arranjo: qualquer um que alcance seu armazenamento terá tanto o bloqueio quanto a chave, e revogar a chave KMS não protege mais nada.
</Warning>

`number_of_bytes` aceita **16, 32 ou 64** e nada mais — 16 para AES-128, 32 para AES-256 (o padrão), 64 para HMAC-SHA512. Qualquer outro valor falha.

<a id="when-direct-encrypt-runs-out" />

### Quando a criptografia direta se esgota

<Warning>
  Uma **chave RSA não pode criptografar mais do que algumas centenas de bytes.** RSA-OAEP só pode carregar uma mensagem menor que o módulo: com SHA-256 que é `k - 2·32 - 2` bytes, então **190 bytes** para `rsa-2048` e **446 bytes** para `rsa-4096` ([RFC 8017 §7.1.1](https://datatracker.ietf.org/doc/html/rfc8017#section-7.1.1)). Não há fragmentação por trás da API. Além desse tamanho, a operação falha e uma chave de dados é a única rota.
</Warning>

Uma chave simétrica não tem um limite algorítmico comparável, mas o corpo da solicitação ainda tem que caber em uma chamada HTTP e você ainda paga uma viagem de ida e volta por operação. Trate a criptografia direta como uma conveniência para valores pequenos e infrequentes, e procure uma chave de dados para tudo o mais.

<a id="encryption-context" />

### Contexto de criptografia

`aad` é opcional, dados autenticados adicionais. Ele está ligado à tag AES-GCM, então um texto cifrado só será aberto se o mesmo contexto for apresentado novamente - útil para fixar um blob à coisa a que pertence, então um texto cifrado roubado não pode ser reproduzido contra um registro diferente.

```json theme={null}
{ "plaintext": "<base64>", "aad": "<base64 of e.g. tenant=42>" }
```

<Warning>
  O contexto deve corresponder ao decrypt **exatamente, incluindo sua ausência**. Fornecer `aad` para descriptografar um texto cifrado que foi selado sem um é recusado em vez de ignorado — um contexto que é apenas às vezes verificado não é uma verificação. Criptografar sem `aad` e descriptografar com ele falha com `400 INVALID_INPUT`.
</Warning>

<Warning>
  Somente uma chave simétrica pode vincular um contexto. Enviar `aad` para criptografar sob uma chave RSA é recusado com `400 KMS_INVALID_KEY_SPEC` — RSA-OAEP não tem onde carregar uma, então aceitá-la deixaria cair a ligação enquanto você continuava tratando-a como uma verificação de integridade. A recusa acontece no selo, onde você ainda pode escolher uma chave diferente.
</Warning>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.