# Canais criptografados

Um canal cujo nome começa com `private-encrypted-` possui criptografia de ponta a ponta. Seu servidor sela cada payload antes de publicá-lo, e clientes de navegador autorizados o descriptografam com uma chave do seu endpoint de autorização. O edge do Realtime e intermediários de rede veem apenas texto cifrado.

Gere e armazene uma chave mestra de 32 bytes. A chave mestra nunca aparece em uma solicitação API do Realtime, e o prefixo do nome do canal habilita o recurso. Bird não consegue recuperar uma chave perdida, e payloads selados com essa chave permanecem ilegíveis após você substituí-la.

Canais criptografados usam o mesmo endpoint e assinatura que os [canais privados](/docs/guides/realtime/private-channels). A resposta de autorização também inclui a chave de descriptografia derivada do canal como `shared_secret`. Rejeitar uma inscrição impede que o cliente receba a chave.

## Gerar uma chave mestra

Gere 32 bytes aleatórios, codifique-os como base64 e armazene o valor como o app secret:

```bash
openssl rand -base64 32
```

Forneça-a ao SDK do seu servidor como parte da configuração do realtime, junto com a app key e o secret.

## Publicar um evento criptografado

O SDK do servidor detecta o prefixo do canal, deriva a chave a partir da chave mestra e sela o payload JSON localmente. A solicitação de publicação contém o envelope selado.

**TypeScript**

```typescript
import { BirdClient } from "@messagebird/sdk";

const bird = new BirdClient({
  apiKey: process.env.BIRD_API_KEY,
  realtime: {
    key: process.env.BIRD_REALTIME_KEY,
    secret: process.env.BIRD_REALTIME_SECRET,
    encryptionMasterKey: process.env.BIRD_REALTIME_MASTER_KEY,
  },
});

await bird.realtime.publish("rap_01krdgeqcxet5s7t44vh8rt9mg", {
  event: "order.updated",
  channels: ["private-encrypted-orders"],
  data: { order_id: "ord_123", status: "shipped" },
});
```

Examples: [TypeScript](/pt-br/documentacao/guides/realtime/encrypted-channels.ts.md) · [Python](/pt-br/documentacao/guides/realtime/encrypted-channels.py.md) · [Go](/pt-br/documentacao/guides/realtime/encrypted-channels.go.md) · [PHP](/pt-br/documentacao/guides/realtime/encrypted-channels.php.md)

Um canal criptografado deve ser o único canal em uma única publicação. Cada canal criptografado deriva uma chave diferente, então outros canais não conseguiriam descriptografar o mesmo payload selado. Os SDKs rejeitam esse fan-out localmente, e o API retorna `E23000` se receber um. Para publicar em vários canais criptografados, use um batch com um canal por evento.

## Retornar o segredo compartilhado do seu endpoint de autenticação

Seu endpoint de autenticação aprova inscrições criptografadas da mesma forma que aprova inscrições privadas. Use o helper `authorizeChannel` do SDK e a resposta ganha o `shared_secret` automaticamente sempre que o nome do canal tiver o prefixo criptografado:

**TypeScript**

```typescript
app.post("/bird/auth", async (req, res) => {
  const { connection_id, channel_name } = req.body;

  const user = getUserFromSession(req);
  if (!user || !mayJoin(user, channel_name)) return res.sendStatus(403);

  res.json(
    await bird.realtime.authorizeChannel({
      connectionId: connection_id,
      channelName: channel_name,
    }),
  );
});
```

Examples: [TypeScript](/pt-br/documentacao/guides/realtime/encrypted-channels.ts.md) · [Python](/pt-br/documentacao/guides/realtime/encrypted-channels.py.md) · [Go](/pt-br/documentacao/guides/realtime/encrypted-channels.go.md) · [PHP](/pt-br/documentacao/guides/realtime/encrypted-channels.php.md)

O SDK deriva um `shared_secret` separado para cada canal. A autorização para `private-encrypted-orders`, portanto, não descriptografa `private-encrypted-invoices`. O segredo trafega na sua resposta de autorização e não é incluído no frame de inscrição enviado ao edge.

## Inscrever-se e descriptografar no navegador

O cifrador usa o ponto de entrada `@messagebird/realtime/encrypted` separado. Importe-o e passe-o como a opção `encryption` do cliente:

```typescript
import { BirdRealtime } from "@messagebird/realtime";
import { encryption } from "@messagebird/realtime/encrypted";

const bird = new BirdRealtime({
  appKey: "your-app-key",
  region: "us1",
  authEndpoint: "/bird/auth",
  encryption,
});

const orders = bird.subscribe("private-encrypted-orders");
orders.bind("order.updated", (data) => {
  console.log(data); // decrypted: { order_id: "ord_123", status: "shipped" }
});
```

Os bindings recebem texto plano. Inscrever-se sem a opção `encryption` lança um erro imediatamente, e uma resposta de autorização sem `shared_secret` falha na inscrição.

Apenas o cliente de navegador recebe canais criptografados atualmente. Os clientes Swift e Kotlin rejeitam inscrições `private-encrypted-` porque não implementam a descriptografia.

## Rotacionar a chave mestra

Implante a nova chave em todos os publicadores e endpoints de autorização ao mesmo tempo. Durante a rotação:

1. Novas publicações selam sob a nova chave.
2. Um cliente de navegador inscrito que não conseguir descriptografar um evento se reautoriza uma vez e obtém o novo `shared_secret`.
3. Instâncias usando chaves mestras diferentes podem publicar brevemente eventos que alguns clientes não conseguem descriptografar; coordene o rollout entre as instâncias.

Rotacione uma chave vazada ou perdida. A rotação protege payloads futuros, mas não consegue selar novamente eventos anteriores nem revogar cópias da chave antiga.

## O que canais criptografados não fazem

- **Clientes oficiais não suportam eventos de cliente.** O `trigger()` do navegador lança um erro em canais criptografados porque o cliente não sela payloads de cliente para cliente. Não envie eventos de cliente em texto plano a partir de um cliente customizado.
- **Presença e criptografia não podem ser combinadas.** O prefixo `presence-encrypted-` não é suportado. Cache e criptografia funcionam juntos: canais `private-encrypted-cache-` armazenam o evento em cache selado, mas após uma rotação de chave a cópia em cache permanece selada sob a chave antiga até que a próxima publicação a substitua.
- **Nomes de canal e nomes de evento não são criptografados.** Apenas o payload é. Escolha nomes de canal que não revelem o que você está protegendo.
- **O edge do Realtime não consegue inspecionar payloads.** Nomes de canal e de evento permanecem visíveis, enquanto o payload permanece criptografado.

## Próximos passos

- [Autorização de canais](/docs/guides/realtime/authorizing-channels) é o mecanismo de assinatura sobre o qual este guia se baseia.
- [Publicação de eventos](/docs/guides/realtime/publishing-events) cobre as próprias APIs de publicação e batch.
- [Canais de cache](/docs/guides/realtime/cache-channels) explica o replay do último evento que `private-encrypted-cache-` combina.

## Related resources

- [Realtime](/products/realtime) (product)
- [Build your first integration](/learn/paths/integration) (course)
- [Send your first realtime event](/docs/get-started/send-your-first-realtime-event) (docs)

[Get an implementation brief](/learn/workspace?topic=realtime)
