Como a mensagem trafega

Uma mensagem de texto não sai do aparelho como texto. Ela atravessa quatro camadas, cada uma com uma pergunta própria, e o que chega ao servidor da Meta é o resultado das quatro aplicadas em ordem. Entender essa ordem é o que transforma o inspetor de um fluxo de linhas coloridas numa explicação.

1. Protobuf — a estrutura

A primeira camada dá forma à mensagem. O WhatsApp não trafega texto solto: trafega um objeto com um tipo declarado, serializado em Protocol Buffers, o formato binário do Google. Um texto simples é um conversation; um texto com citação ou link vira extendedTextMessage; uma foto é um imageMessage, que carrega não a foto, mas a chave e o endereço de onde baixá-la.

É a camada que responde “o que é isto?”. E é importante notar que ela ainda está em claro: nada foi cifrado até aqui. O Protobuf é compactação e estrutura, não sigilo — quem tiver o buffer nesta etapa lê a mensagem inteira.

2. Signal — o sigilo do conteúdo

Agora o objeto do Protobuf é cifrado com o protocolo Signal, o mesmo do aplicativo homônimo. É esta camada, e só ela, que garante que a Meta não lê o que você escreveu.

A cifragem acontece uma vez por dispositivo. Se o destinatário tem celular, WhatsApp Web e um tablet, a mesma mensagem é cifrada três vezes, com três chaves distintas, e três pacotes diferentes saem pela rede. Não existe cifrar uma vez e distribuir: cada aparelho tem seu próprio canal criptográfico. É por isso que a ferramenta informa quantos dispositivos receberam, e por que a lista de canais Signal é mais longa que a lista de contatos.

Dentro de cada canal, o Double Ratchet troca a chave a cada mensagem. Duas mensagens seguidas para a mesma pessoa não usam a mesma chave, e a chave de ontem não abre a mensagem de hoje. A consequência é o forward secrecy: comprometer o estado atual não entrega o histórico, porque as chaves antigas já foram descartadas e não há como recalculá-las a partir da atual.

3. WABinary — o endereçamento

O pacote cifrado agora precisa de um envelope que diga para onde vai. Esse envelope é um nó XMPP binário tokenizado — a estrutura em árvore do XMPP clássico (<message to="…" id="…">), só que serializada em binário em vez de texto.

A tokenização é o truque de economia: em vez de escrever a palavra message em nove bytes, o WABinary a substitui por um único byte, consultando um dicionário de tokens que cliente e servidor compartilham. Palavras frequentes do protocolo — message, receipt, iq, nomes de atributo, domínios — têm entrada nesse dicionário mantido pela Meta. Só o que não está nele viaja como texto.

Esta camada não cifra nada. É metadado, e o servidor precisa lê-lo para fazer o trabalho dele: rotear. Quem falou com quem, quando e de que tipo era a mensagem fica visível aqui — o que está protegido é o conteúdo, não o fato de a conversa existir.

Como o dicionário é da Meta e muda sem aviso, uma tag que a ferramenta não conhece é o sinal mais precoce de que o protocolo mudou — costuma aparecer antes de a conexão cair. O inspetor marca esses nós justamente para que a incompatibilidade seja notada enquanto ainda é curiosidade, e não depois de já ter derrubado a sessão.

4. Noise — o sigilo do canal

Por último, o nó inteiro — envelope e tudo — é cifrado de novo, agora com o Noise Protocol Framework, o mesmo framework que o WireGuard usa. A conexão começa com um handshake que estabelece as chaves do canal, e a partir daí todos os frames trafegam cifrados até o servidor.

Esta camada protege contra quem está no caminho: o Wi-Fi do café, o provedor, um proxy corporativo. Ninguém entre você e a Meta consegue ver sequer os nós WABinary — só um fluxo de bytes opacos.

O ponto central: são duas criptografias opostas

A confusão mais comum é achar que Noise e Signal são redundantes. São o contrário disso: têm propósitos opostos, e é a combinação dos dois que define o modelo de confiança do WhatsApp.

Noise

Protege a conversa com o servidor.

O servidor é o outro lado do canal — ele decifra, porque precisa. Protege contra terceiros na rede.

Signal

Protege o conteúdo do servidor.

O servidor não tem a chave e não decifra. Protege contra a própria Meta.

Colocando as duas juntas: a Meta decifra o Noise, lê o envelope WABinary, descobre para quem entregar, e repassa adiante o pacote Signal — que ela não consegue abrir. Ela roteia sem conseguir ler. O metadado é dela; o conteúdo, não.

Resumo

CamadaPapelCifra?Pergunta que responde
ProtobufEstruturaNão cifraQue tipo de mensagem é esta?
SignalSigilo do conteúdoPonta a pontaComo só o destinatário lê isto?
WABinaryEndereçamentoNão cifraPara onde isto vai, e o que o servidor precisa saber?
NoiseSigilo do canalCliente ↔ servidorComo ninguém no caminho vê o tráfego?

Na chegada, o caminho é o mesmo de trás para frente: decifra o Noise, lê o nó WABinary, decifra o Signal, desserializa o Protobuf — e só então existe uma mensagem legível.

Nada disso é documentação publicada pela Meta. O protocolo Multi-Device é fechado, e o que se sabe dele vem de engenharia reversa da comunidade — inclusive o dicionário de tokens do WABinary e o formato dos nós. É conhecimento sólido o bastante para funcionar, mas pode mudar sem aviso, e uma quebra costuma ser descoberta pela sessão que caiu.

O inspetor da ferramenta em /protocolo mostra isso ao vivo: cada evento chega marcado com a camada a que pertence, e o nó pode ser aberto para ver o XML cru por trás dele. É o mesmo caminho descrito aqui, só que acontecendo.