Como HTTPS e TLS realmente funcionam: o handshake explicado
Você adicionou um certificado, o navegador mostra o cadeado e você segue em frente. Então, um dia, um cliente de API falha com SSL_ERROR_RX_RECORD_TOO_LONG, um app mobile rejeita sua cadeia ou um loop de redirecionamento aparece após ativar o HSTS. De repente, o HTTPS parece uma caixa preta.
Este artigo abre essa caixa. Vamos percorrer o que realmente acontece durante um handshake TLS, por que os certificados existem, onde a criptografia simétrica e assimétrica se encaixam e como depurar as falhas que você realmente encontrará em produção.
O que HTTPS realmente é
HTTPS não é um protocolo separado. É HTTP simples enviado por uma conexão criptografada com TLS. O esquema da URL muda, a porta padrão passa de 80 para 443 e todo o resto — métodos, cabeçalhos, códigos de status, cookies — se comporta da mesma forma.
O TLS oferece três garantias sobre o TCP:
- Confidencialidade — intermediários não podem ler o tráfego.
- Integridade — adulterações em trânsito são detectadas.
- Autenticação — o cliente pode verificar que está falando com o servidor que possui o domínio.
Essa terceira garantia é a que as pessoas subestimam. Criptografia sem autenticação é inútil: um atacante que pode interceptar o tráfego poderia simplesmente apresentar sua própria chave.
O handshake TLS 1.3, passo a passo
O TLS 1.3 simplificou drasticamente o handshake em comparação com o TLS 1.2. Veja o fluxo entre um navegador e um servidor:
- ClientHello — o cliente envia as versões de TLS suportadas, conjuntos de cifras, um valor aleatório e uma chave compartilhada para um grupo Diffie-Hellman (por exemplo, X25519).
- ServerHello — o servidor escolhe um conjunto de cifras e envia sua própria chave compartilhada. Ambos os lados agora podem derivar o mesmo segredo compartilhado.
- Extensões criptografadas e certificado — o servidor envia sua cadeia de certificados, já criptografada com as chaves derivadas.
- Finished — ambos os lados enviam um MAC sobre o transcript do handshake para provar que nada foi adulterado.
- Dados da aplicação — as requisições e respostas HTTP fluem sobre a sessão estabelecida.
No TLS 1.3, o handshake completo custa uma viagem de ida e volta, e a retomada pode chegar a zero viagens. O TLS 1.2 precisava de duas viagens antes que qualquer dado da aplicação pudesse fluir.
Por que o certificado é enviado depois que as chaves são derivadas
No TLS 1.3, o certificado é criptografado. Isso significa que um observador passivo não consegue nem ver qual domínio o cliente está visitando apenas pelo certificado, o que reduz o vazamento de informações. Também significa que ferramentas de depuração que esperam um certificado em texto claro nos primeiros pacotes ficarão confusas.
Criptografia simétrica vs assimétrica
Um equívoco comum é que o HTTPS criptografa tudo com a chave pública do servidor. Não é o caso. A criptografia assimétrica é lenta e limitada em tamanho; ela é usada apenas para estabelecer um segredo compartilhado.
| Etapa | Criptografia | Propósito |
|---|---|---|
| Troca de chaves | Assimétrica (ECDHE) | Concordar com um segredo compartilhado sem enviá-lo |
| Autenticação | Assinaturas assimétricas | Provar que o servidor possui a chave do certificado |
| Dados em massa | Simétrica (AES-GCM ou ChaCha20-Poly1305) | Criptografia e integridade rápidas para o tráfego HTTP |
A troca de chaves Diffie-Hellman tem uma propriedade valiosa chamada sigilo forward secrecy: mesmo que a chave privada do servidor vaze depois, sessões passadas gravadas não podem ser descriptografadas, porque as chaves de sessão nunca foram derivadas dessa chave de longo prazo.
O que há dentro de um certificado
Um certificado X.509 vincula uma chave pública a um nome de domínio. Ele contém:
- O assunto (domínio) e os nomes alternativos do assunto (SANs), que é o que os navegadores realmente verificam.
- A chave pública e seu algoritmo.
- O período de validade.
- O emissor e uma assinatura desse emissor.
Os navegadores confiam em um conjunto fixo de autoridades certificadoras raiz. Seu servidor envia um certificado intermediário, e o navegador constrói uma cadeia do seu certificado folha até uma raiz confiável. Se o intermediário estiver faltando, navegadores de desktop podem ainda funcionar porque armazenam intermediários em cache, enquanto clientes móveis e ferramentas de linha de comando falham. Este é o erro de TLS em produção mais comum.
Passos práticos de depuração
Quando o HTTPS se comporta mal, trabalhe de fora para dentro.
- Verifique a cadeia com
openssl s_client -connect example.com:443 -servername example.com -showcerts. Confirme que o servidor envia a cadeia completa, não apenas a folha. - Verifique a expiração — certificados expirados produzem falhas graves sem solução alternativa.
- Verifique o hostname — a lista de SANs deve conter o hostname exato solicitado pelo cliente, incluindo qualquer prefixo
www. - Verifique a versão do protocolo — se um cliente legado só suporta TLS 1.0 e seu servidor exige TLS 1.2+, o handshake falha antes do HTTP.
- Verifique redirecionamentos — um redirecionamento de HTTPS para HTTP e de volta cria um loop; corrija na configuração do servidor, não no código da aplicação.
# Inspecione a cadeia de certificados e o protocolo negociado
openssl s_client -connect example.com:443 \
-servername example.com -showcerts < /dev/null 2>&1 | \
openssl x509 -noout -subject -issuer -dates
# Teste uma versão específica do TLS
openssl s_client -connect example.com:443 -tls1_2 < /dev/nullNo Nginx, a diretiva ssl_certificate deve apontar para um arquivo contendo o certificado folha seguido do intermediário, nessa ordem. Concatená-los na ordem errada produz erros de cadeia fáceis de passar despercebidos.
HSTS e o custo de errar
HTTP Strict Transport Security diz aos navegadores para usar HTTPS em um domínio por um período determinado. É poderoso e implacável: uma vez que um navegador viu um max-age longo, ele recusará HTTP simples mesmo que você desative o HTTPS no servidor depois.
Comece com um max-age curto, verifique se tudo funciona e então aumente. Adicione includeSubDomains apenas depois que todos os subdomínios servirem HTTPS válido. O preload é efetivamente permanente — só o solicite quando tiver certeza.
Configurações incorretas comuns
- Conteúdo misto — uma página HTTPS carregando scripts ou imagens via HTTP. Navegadores bloqueiam conteúdo misto ativo e avisam sobre conteúdo passivo.
- Conjuntos de cifras fracos — deixar cifras em modo CBC e versões antigas de protocolo habilitadas por compatibilidade que você não precisa mais.
- Falta de tratamento de OCSP ou CRL — a verificação de revogação é não confiável na prática; certificados de curta duração são a resposta mais robusta.
- Lacunas na automação de certificados — a renovação funciona, mas falta a etapa de recarregar que faz o servidor pegar o novo certificado.
Trate a renovação de certificados como um pipeline de implantação, não como um lembrete de calendário. Se a renovação exige um humano, ela eventualmente falhará no pior momento.
Perguntas frequentes
O HTTPS criptografa o nome de domínio que eu visito?
O domínio aparece na extensão SNI do TLS e geralmente é visível na rede. O caminho e a string de consulta são criptografados, mas um observador da rede normalmente consegue ver a qual host você se conectou.
Por que meu site funciona no navegador mas falha no curl ou em um app mobile?
Quase sempre é um certificado intermediário ausente. Navegadores frequentemente armazenam intermediários em cache de visitas anteriores, enquanto curl e muitas pilhas HTTP móveis exigem que o servidor envie a cadeia completa.
O TLS 1.3 é sempre melhor que o TLS 1.2?
Para clientes modernos, sim — menos viagens de ida e volta, um conjunto menor de cifras e sigilo forward secrecy por padrão. Mantenha o TLS 1.2 habilitado apenas se você ainda atende clientes que não conseguem negociar o 1.3.
Quando precisar inspecionar logs dos servidores que terminam o TLS, uma passada rápida pelo analisador de logs do Nginx ajuda a identificar falhas de handshake, loops de redirecionamento e comportamentos incomuns de clientes antes que se tornem indisponibilidades.