Toda requisição HTTPS começa com uma conversa que a maioria dos engenheiros nunca olha. Antes de o seu navegador enviar GET /, ele e o servidor combinam uma versão de protocolo, trocam chaves, verificam um certificado e provam que ninguém adulterou nada disso. Quando isso dá errado, você recebe erros enigmáticos como handshake_failure ou bad_certificate, e quando fica lento, toda página paga o preço.
O TLS 1.3 deixou o handshake mais curto e mais privado que o TLS 1.2. Este post o percorre mensagem por mensagem com um diagrama de sequência e depois cobre as variações que você encontra em produção: HelloRetryRequest, retomada de sessão e 0-RTT, TLS mútuo, Encrypted Client Hello e troca de chaves pós-quântica.
O que o handshake precisa alcançar
Um handshake TLS cumpre quatro tarefas antes que qualquer dado da aplicação flua:
- Negociar parâmetros: a versão do protocolo, a cipher suite e o grupo de troca de chaves.
- Estabelecer chaves compartilhadas: os dois lados derivam os mesmos segredos sem nunca enviá-los.
- Autenticar o servidor, e opcionalmente o cliente, com certificados.
- Confirmar a integridade: os dois lados verificam que viram as mesmas mensagens do handshake, para que um atacante não consiga rebaixar nem alterar a negociação.
A especificação atual é a RFC 9846, publicada em julho de 2026. Ela substitui a RFC 8446, mas mantém a mesma versão de protocolo, então um cliente TLS 1.3 feito com base na RFC antiga continua conversando com um servidor feito com base na nova.
O handshake completo, mensagem por mensagem
O TLS 1.3 precisa de uma ida e volta. O cliente tenta adivinhar qual troca de chaves o servidor vai aceitar e envia a sua metade da troca já na primeira mensagem.
| Mensagem | Direção | Criptografada | O que leva |
|---|---|---|---|
| ClientHello | cliente → servidor | Não | Valor aleatório, cipher suites, supported_versions, key_share, signature_algorithms, server_name (SNI), ALPN |
| ServerHello | servidor → cliente | Não | Cipher suite escolhida, o key_share do servidor |
| EncryptedExtensions | servidor → cliente | Sim | Demais extensões negociadas, como o protocolo ALPN |
| Certificate | servidor → cliente | Sim | A cadeia de certificados do servidor |
| CertificateVerify | servidor → cliente | Sim | Uma assinatura sobre o handshake até ali, feita com a chave privada do certificado |
| Finished | servidor → cliente | Sim | Um MAC sobre toda a transcrição |
| Finished | cliente → servidor | Sim | O MAC do cliente sobre a transcrição |
A linha importante é a que vem depois do ServerHello. Assim que o cliente tem o key share do servidor, os dois lados executam o key schedule (HKDF sobre o segredo compartilhado e a transcrição) e derivam as chaves de tráfego do handshake. Daí em diante, toda mensagem do handshake é criptografada. No TLS 1.2, um observador na rede conseguia ler o certificado do servidor; no TLS 1.3, não consegue.
O CertificateVerify prova que o servidor tem a chave privada do certificado que acabou de enviar. O Finished prova que os dois lados viram as mesmas mensagens. Se um atacante removesse uma cipher suite do ClientHello, as transcrições seriam diferentes e a verificação do Finished falharia.
O servidor pode enviar dados da aplicação logo depois do seu Finished, e o cliente envia a primeira requisição imediatamente depois do próprio Finished. Uma ida e volta depois do ClientHello, a conexão criptografada está pronta.
O que mudou desde o TLS 1.2
| TLS 1.2 | TLS 1.3 | |
|---|---|---|
| Idas e voltas para uma nova conexão | 2 | 1 |
| Troca de chaves | Transporte de chave RSA ou (EC)DHE | Só (EC)DHE, ou PSK com (EC)DHE |
| Sigilo direto | Opcional | Sempre, exceto na retomada só com PSK |
| Cipher suites | Dezenas, incluindo CBC e RC4 | Cinco, todas AEAD |
| Certificado do servidor na rede | Em texto claro | Criptografado |
| Compressão e renegociação | Suportadas | Removidas |
A lista de cipher suites encolheu para TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256 e duas suites CCM. Uma cipher suite do TLS 1.3 agora nomeia só a criptografia dos registros e o hash; a troca de chaves e o algoritmo de assinatura são negociados separadamente. Certificados RSA continuam funcionando. O que sumiu foi o transporte de chave RSA, em que o cliente criptografava o segredo com a chave pública do servidor e uma chave roubada decifrava toda sessão gravada.
Quando uma ida e volta vira duas: HelloRetryRequest
O handshake de uma ida e volta depende de um palpite. O cliente envia key shares para os grupos que espera que o servidor aceite, geralmente X25519. Se o servidor não suportar nenhum deles, responde com um HelloRetryRequest indicando um grupo que aceita, e o cliente recomeça com um novo ClientHello. Isso custa uma ida e volta inteira a mais.
Você vê isso quando cliente e servidor discordam sobre os grupos, por exemplo um servidor configurado só para P-256 e um cliente que envia só um share X25519. A solução é configuração: garanta que os grupos que seus clientes oferecem primeiro sejam os que seus servidores preferem.
Retomada e 0-RTT
Depois do handshake, o servidor pode enviar mensagens NewSessionTicket. Um ticket permite que o cliente retome mais tarde com uma chave pré-compartilhada (PSK), em vez de uma troca completa de certificados. A retomada normalmente ainda executa uma nova troca (EC)DHE, então a sessão retomada mantém o sigilo direto.
Com um ticket, o cliente também pode enviar dados antecipados, chamados de 0-RTT: a primeira requisição viaja no mesmo voo que o ClientHello. Isso economiza uma ida e volta, mas a RFC 9846 deixa explícito que dados 0-RTT não têm garantia contra replay entre conexões. Um atacante que capture o primeiro voo pode enviá-lo de novo.
As regras práticas:
- Envie como dados antecipados só requisições idempotentes:
GETsem efeitos colaterais, nunca um pagamento ou um pedido. - No servidor, habilite o 0-RTT só onde a aplicação consiga rejeitar ou tolerar replays. Muitos servidores marcam as requisições com dados antecipados (por exemplo, com o cabeçalho
Early-Data: 1definido na RFC 8470), para que a aplicação possa responder425 Too Early. - Não use 0-RTT em ações autenticadas, a menos que você tenha pensado bem no replay.
TLS mútuo
No TLS mútuo (mTLS), o servidor também pede um certificado ao cliente. O servidor adiciona um CertificateRequest depois do EncryptedExtensions, e o cliente responde com o próprio Certificate e o CertificateVerify antes do seu Finished. O número de idas e voltas não muda.
O mTLS é o padrão entre serviços em uma malha: cada workload recebe um certificado de vida curta, e sidecars ou proxies cuidam do handshake. O diagrama de arquitetura de service mesh mostra de onde vêm esses certificados, e o diagrama de arquitetura zero trust explica por que a identidade por requisição importa mais do que a rede de onde a requisição veio.
Privacidade e chaves pós-quânticas: o que há de novo em 2026
Duas RFCs recentes mudam a aparência do handshake na rede.
Encrypted Client Hello. O ClientHello é enviado antes de existir qualquer chave, então o SNI, o nome de host que o cliente quer, trafega em texto claro. A RFC 9849, publicada em março de 2026, define o Encrypted Client Hello (ECH): o cliente criptografa um ClientHello interno, incluindo o nome de host real, com uma chave que o servidor publica no DNS. Os observadores veem só um nome externo público, normalmente o de um grande provedor.
Troca de chaves pós-quântica híbrida. O tráfego gravado hoje pode ser decifrado no futuro por um computador quântico, então a troca de chaves é a primeira a mudar. A RFC 10024, publicada em agosto de 2026, define híbridos como o X25519MLKEM768, que combina X25519 com ML-KEM-768. Os dois shares alimentam o key schedule, então a conexão continua segura enquanto qualquer um dos dois algoritmos resistir. Chrome e Edge 131 ou mais recentes e Firefox 132 ou mais recente oferecem isso por padrão.
O custo é o tamanho. Um share de cliente X25519MLKEM768 tem 1.216 bytes e o do servidor 1.120 bytes, contra 32 bytes cada no X25519 puro. Um ClientHello agora pode ocupar dois pacotes, o que expôs middleboxes que supunham que isso nunca aconteceria.
O custo em idas e voltas
São as idas e voltas, e não a banda, que decidem a rapidez com que uma conexão fica pronta. Com uma ida e volta de 100 ms entre cliente e servidor, sem contar o DNS:
| Configuração | Idas e voltas antes da resposta | Tempo |
|---|---|---|
| TCP + TLS 1.2 + requisição | 4 | 400 ms |
| TCP + TLS 1.3 + requisição | 3 | 300 ms |
| TCP + TLS 1.3 com 0-RTT | 2 | 200 ms |
| QUIC (HTTP/3), nova conexão | 2 | 200 ms |
| QUIC com 0-RTT | 1 | 100 ms |
O QUIC carrega o mesmo handshake TLS 1.3 dentro dos próprios pacotes (RFC 9001) e o funde com o handshake de transporte, e é aí que a ida e volta extra desaparece. Terminar o TLS perto dos usuários, em um CDN ou em um balanceador de carga na borda, encurta a própria ida e volta; o diagrama de balanceador de carga mostra onde a terminação costuma acontecer.
O diagrama do handshake
Conteúdo do diagrama
- Client (browser)
- Server
- mutual TLS only
- ClientHello: key_share, supported_versions, SNI, ALPN
- ServerHello: key_share, chosen cipher suite
- {EncryptedExtensions}
- {CertificateRequest} (mTLS only)
- {Certificate}: server chain
- {CertificateVerify}: signature over the transcript
- {Finished}: MAC over the transcript
- {Certificate}: client chain
- {CertificateVerify}
- {Finished}
- [Application data], both directions
- NewSessionTicket (for resumption)
Como ler:
- Duas linhas de vida. O cliente à esquerda, o servidor à direita. O tempo corre para baixo.
- As setas simples são enviadas em texto claro: ClientHello e ServerHello. Tudo abaixo da linha marcada como “handshake keys” é criptografado.
- O voo do servidor leva EncryptedExtensions, Certificate, CertificateVerify e Finished de uma vez, e é por isso que o handshake cabe em uma ida e volta.
- O fragmento opcional contém o Certificate e o CertificateVerify do cliente, enviados só no TLS mútuo. O CertificateRequest tracejado no voo do servidor é o que os pede.
- O bloco Markdown lista as extensões que decidem se o handshake dá certo: versões, grupos, algoritmos de assinatura, SNI e ALPN.
Desenhar diagramas de protocolo que ajudam a depurar
- Marque a fronteira da criptografia. A pergunta mais comum sobre TLS é o que um observador consegue ver. Trace a linha.
- Nomeie as extensões que importam, não todas.
key_shareesupported_versionsexplicam a maioria das falhas. - Coloque caminhos opcionais e alternativos em fragmentos. Um fragmento
optpara os certificados do cliente e um fragmentoaltpara o HelloRetryRequest mantêm o fluxo principal legível. - Um diagrama por pergunta. Um handshake completo, uma retomada com 0-RTT e uma troca mTLS são três diagramas se cada um precisar de detalhes.
O exemplo de diagrama de sequência trata com mais profundidade de linhas de vida, fragmentos e convenções de nomes.
Monte no Archboard
- Entre com Google ou GitHub e crie um diagrama.
- Adicione dois nós Linha de vida do pack Sequência, chamados Client e Server.
- Desenhe as mensagens como arestas entre as linhas de vida, de cima para baixo: ClientHello, ServerHello, depois as quatro mensagens criptografadas do servidor e o Finished do cliente. Rotule cada aresta com o nome da mensagem e seus campos principais.
- Adicione um Fragmento combinado do pack Sequência com o operador
optem volta do Certificate e do CertificateVerify do cliente, e desenhe o CertificateRequest do servidor como uma aresta tracejada. - Adicione um bloco Markdown do pack Básico com as extensões e o número de idas e voltas, e uma Nota marcando onde a criptografia começa.
O exemplo usa 4 nós de diagrama e fica dentro do plano Free.
Perguntas frequentes
Quantas idas e voltas leva um handshake TLS 1.3? Uma para uma nova conexão, contra duas no TLS 1.2. Um HelloRetryRequest acrescenta uma segunda, e a retomada com 0-RTT permite que o cliente envie a primeira requisição sem nenhuma ida e volta de handshake.
O certificado do servidor é criptografado no TLS 1.3? Sim. Tudo depois do ServerHello, incluindo a mensagem Certificate, é criptografado com as chaves do handshake. O ClientHello não é, e essa é a lacuna que o Encrypted Client Hello fecha.
É seguro habilitar o 0-RTT? Só para requisições que podem ser repetidas com segurança. Dados antecipados podem ser capturados e reenviados, então limite-os a requisições idempotentes e deixe a aplicação rejeitar todo o resto com 425 Too Early.
O TLS 1.3 ainda suporta certificados RSA? Sim. Assinaturas RSA continuam sendo usadas para autenticar servidores. O TLS 1.3 removeu o transporte de chave RSA, em que o segredo da sessão era criptografado com a chave RSA do servidor e uma chave vazada expunha o tráfego passado.
Qual é a diferença entre TLS e mTLS? No TLS comum, só o servidor apresenta um certificado. No TLS mútuo, o servidor também pede um certificado ao cliente, então os dois lados se autenticam no mesmo handshake.