Pular para o conteúdo

Diagrama do handshake TLS 1.3: passo a passo, com retomada de sessão e mTLS

O handshake do TLS 1.3 em diagrama: o que cada mensagem leva, o que é criptografado e como a retomada, o 0-RTT, o mTLS e a troca de chaves pós-quântica o mudam.

· Fundador e desenvolvedor

Publicado em

Linhas de vida do cliente e do servidor. Sai o ClientHello com key shares; volta o ServerHello e depois, criptografados, EncryptedExtensions, Certificate, CertificateVerify e Finished. O cliente envia Finished e os dados fluem. Um fragmento opt mostra certificados do cliente.

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:

  1. Negociar parâmetros: a versão do protocolo, a cipher suite e o grupo de troca de chaves.
  2. Estabelecer chaves compartilhadas: os dois lados derivam os mesmos segredos sem nunca enviá-los.
  3. Autenticar o servidor, e opcionalmente o cliente, com certificados.
  4. 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: GET sem 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: 1 definido na RFC 8470), para que a aplicação possa responder 425 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

Linhas de vida do cliente e do servidor. Sai o ClientHello com key shares; volta o ServerHello e depois, criptografados, EncryptedExtensions, Certificate, CertificateVerify e Finished. O cliente envia Finished e os dados fluem. Um fragmento opt mostra certificados do cliente.

5 componentes · 12 conexões

Abrir no Archboard
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)
Um handshake TLS 1.3 completo entre um navegador e um servidor. Uma ida e volta estabelece as chaves; tudo depois do ServerHello é criptografado, inclusive o certificado. O bloco opcional mostra as mensagens extras do TLS mútuo.

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_share e supported_versions explicam a maioria das falhas.
  • Coloque caminhos opcionais e alternativos em fragmentos. Um fragmento opt para os certificados do cliente e um fragmento alt para 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

  1. Entre com Google ou GitHub e crie um diagrama.
  2. Adicione dois nós Linha de vida do pack Sequência, chamados Client e Server.
  3. 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.
  4. Adicione um Fragmento combinado do pack Sequência com o operador opt em volta do Certificate e do CertificateVerify do cliente, e desenhe o CertificateRequest do servidor como uma aresta tracejada.
  5. 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.

Comece grátis — um assento, sem cartão de crédito.

Artigos relacionados

← Voltar ao blog

Abra um canvas em um minuto

Entre com Google ou GitHub. Grátis para um assento. Faça upgrade quando a equipe entrar.