Pular para o conteúdo

TLS por dentro: como a internet protege os dados em trânsito

Uma imersão no TLS, o protocolo por trás do cadeado do navegador. O handshake, os certificados, os ataques que o moldaram e a criptografia pós-quântica.

Equipe Gothor· Publicado em · Atualizado em · 52 min de leitura
Capa do artigo TLS por dentro, com o handshake do TLS 1.3 entre cliente e servidor, a cadeia de certificados e as versões do protocolo

Um pedido que sai do Winthor para a API de um banco, a senha digitada no internet banking, o boleto que chega por e-mail, a nota fiscal enviada à Sefaz: tudo isso atravessa redes que ninguém da empresa controla. O Wi-Fi do escritório, o provedor de internet, os roteadores de outras operadoras e os servidores do outro lado do país enxergam os pacotes passando. Sem proteção, qualquer um desses pontos poderia ler o conteúdo, alterá-lo no caminho ou se passar pelo destino. O protocolo que impede isso na maior parte do tráfego da internet é o TLS, o Transport Layer Security.

O TLS é discreto. Quase ninguém o configura no dia a dia, e quem usa só percebe que ele existe pelo cadeado ao lado do endereço no navegador ou por uma mensagem de erro de certificado. Mas é ele que decide se uma conexão é confiável: quais algoritmos serão usados, como as chaves são combinadas sem nunca passar pela rede, como o servidor prova que é quem diz ser e como cada pedaço de dado chega íntegro ao outro lado. Quando algo dá errado, como um certificado vencido, uma versão antiga recusada por um banco ou uma biblioteca desatualizada, o efeito aparece rápido: integrações param, e-mails deixam de sair, clientes veem alertas assustadores.

Este artigo é uma imersão no TLS: a história, do SSL da Netscape ao TLS 1.3; o protocolo por dentro, do handshake aos certificados; os ataques que o moldaram e a configuração recomendada; o TLS mútuo dos bancos, a criptografia pós-quântica e, no fim, os princípios que seguimos na Gothor.

O problema que o TLS resolve

A internet foi construída sobre protocolos que não escondem nada. O IP entrega pacotes de roteador em roteador, e cada roteador lê o cabeçalho para decidir o próximo salto. O TCP garante que os bytes cheguem em ordem, mas os bytes viajam como foram escritos. Um HTTP sem proteção leva a senha, o cookie de sessão e o conteúdo da página em texto puro. Quem estiver no caminho, legitimamente ou não, pode ler tudo.

A documentação da Microsoft resume em três os riscos que o TLS foi feito para detectar: a adulteração de mensagens, a interceptação de mensagens e a falsificação de mensagens [6]. Cada risco corresponde a uma garantia:

  • Confidencialidade. Os dados trocados depois que a conexão se estabelece só são legíveis para as duas pontas. Quem captura os pacotes vê bytes sem sentido.
  • Integridade. Qualquer alteração no caminho é detectada. Um byte trocado num registro faz a verificação falhar, e a conexão é encerrada em vez de entregar dados adulterados.
  • Autenticação. O cliente tem como verificar que está falando com o servidor certo, e não com alguém que se colocou no meio. O servidor também pode exigir que o cliente prove a identidade, o que é comum entre empresas e bancos.

As três garantias dependem umas das outras. Cifrar sem autenticar não adianta: um atacante no meio do caminho negociaria uma conexão cifrada com a vítima e outra com o servidor verdadeiro, e leria tudo no meio. Por isso a especificação descreve o TLS como um canal entre duas pontas resistente, ao mesmo tempo, a escuta, adulteração e falsificação [1].

Quando o financeiro de uma distribuidora envia boletos para a API de um banco, a confidencialidade impede que alguém no provedor leia os dados dos pagadores, a integridade impede que o valor seja trocado no caminho e a autenticação garante que o pedido chegou ao banco, e não a um servidor falso.

Do SSL ao TLS 1.3: uma história em versões

O TLS tem um antecessor com outro nome. A Netscape, empresa do navegador mais usado em meados dos anos 1990, desenvolveu o SSL (Secure Sockets Layer) em 1994 para proteger o comércio eletrônico que começava a surgir [4][5]. A versão 3.0 do SSL saiu em 1996 e serviu de base para o que viria depois [4].

Na virada para 1999, a padronização passou para a IETF, a organização que publica as especificações da internet. A IETF renomeou o protocolo para TLS e publicou o TLS 1.0 em janeiro de 1999, na RFC 2246, como uma atualização modesta do SSL 3.0 que corrigia defeitos e proibia algoritmos sabidamente fracos [5]. A troca de nome não mudou o hábito: até hoje se fala em "certificado SSL" e em "SSL" para qualquer conexão cifrada, quase sempre querendo dizer TLS.

As versões seguintes responderam a ataques e a algoritmos que envelheceram:

  • TLS 1.1, em 2006 (RFC 4346), acrescentou proteção contra ataques ao vetor de inicialização do modo CBC [4].
  • TLS 1.2, em agosto de 2008 (RFC 5246), trouxe algoritmos de hash mais fortes, como o SHA-256, e mais flexibilidade na escolha das suítes de cifras [3][4]. Foi a versão dominante por uma década.
  • TLS 1.3, em agosto de 2018 (RFC 8446), foi uma reformulação profunda: removeu algoritmos obsoletos, simplificou o handshake e passou a cifrar quase toda a negociação [2][4].

A história também tem as despedidas. O SSL 2.0 foi proibido pela RFC 6176, de 2011, e o SSL 3.0 pela RFC 7568, de junho de 2015, que diz sem rodeios que ele não deve ser usado, citando entre os motivos o ataque POODLE [10]. O RC4, uma cifra de fluxo que já foi uma das mais usadas no TLS, foi proibido em todas as versões pela RFC 7465, de fevereiro de 2015 [9]. Em 2021, a RFC 8996 tirou de circulação o TLS 1.0, o TLS 1.1 e o DTLS 1.0, movendo as especificações para o status de históricas [8].

O capítulo mais recente é de julho de 2026: a RFC 9846 substituiu a RFC 8446 como a especificação do TLS 1.3 [1]. Não é uma versão nova. O documento se define como uma atualização menor, que mantém o número da versão e é compatível com o que já existe; ele consolida correções acumuladas, proíbe expressamente negociar o TLS 1.0 e o 1.1, proíbe reaproveitar a mesma parte da troca de chaves entre conexões, generaliza o texto para acomodar mecanismos de encapsulamento de chaves (o caminho para a criptografia pós-quântica) e deixa obsoletas, de uma vez, a RFC 8446 e a RFC 5246, do TLS 1.2 [1].

Linha do tempo do TLS: o SSL da Netscape em 1994, o SSL 3.0 em 1996, o TLS 1.0 em 1999, o TLS 1.1 em 2006, o TLS 1.2 em 2008, o Heartbleed e o POODLE em 2014, a proibição do RC4 e do SSL 3.0 em 2015, o TLS 1.3 em 2018, a RFC 8996 que aposenta o TLS 1.0 e o 1.1 em 2021, o padrão ML-KEM do NIST em 2024 e a RFC 9846 em 2026
Do SSL da Netscape ao TLS 1.3 revisado: três décadas de correções, ataques e despedidas

Onde o TLS fica na pilha

O TLS mora entre a aplicação e o transporte. A documentação da Microsoft descreve o protocolo como uma camada situada entre o protocolo da aplicação e o TCP/IP, que protege os dados da aplicação antes de entregá-los ao transporte, e lembra que o TLS supõe um transporte orientado a conexão, tipicamente o TCP [6]. Como fica nesse meio, o mesmo TLS serve a vários protocolos de aplicação sem que eles precisem saber de criptografia [6].

Essa posição explica os nomes que aparecem no dia a dia:

  • HTTPS é o HTTP dentro de uma conexão TLS, normalmente na porta 443.
  • SMTPS, IMAPS e POP3S são os protocolos de e-mail dentro do TLS desde o primeiro byte, o chamado TLS implícito, em portas próprias (465, 993 e 995).
  • STARTTLS é o outro jeito de proteger o e-mail: a conexão começa em texto puro, na porta de sempre, e o cliente pede para subir para o TLS no meio da conversa. A RFC 7457 registra que esse caminho tem riscos próprios, como comandos injetados antes da troca e ataques que simplesmente apagam o pedido de STARTTLS [7].
  • DTLS é a variante do TLS para datagramas, usada sobre o UDP, onde não há conexão TCP. A RFC 8996 aposentou a versão 1.0 dele junto com o TLS 1.0 e o 1.1 [8].
  • QUIC, o transporte sobre UDP que sustenta o HTTP/3, não roda "por cima" do TLS como o HTTPS clássico: ele usa o handshake do TLS 1.3 por dentro, para combinar chaves e autenticar o servidor, e cifra os próprios pacotes com elas, como descreve a RFC 9001, de 2021 [22].

Fora do navegador, o TLS protege também mensageiros instantâneos e voz sobre IP [4].

ALPN: qual protocolo vai dentro do túnel

A mesma porta 443 pode carregar o HTTP/1.1 ou o HTTP/2, e o servidor precisa saber qual dos dois o cliente vai falar assim que a conexão estiver pronta. Perguntar depois custaria mais uma ida e volta. A extensão ALPN (Application-Layer Protocol Negotiation), publicada na RFC 7301 em julho de 2014, resolve isso dentro do próprio handshake: o cliente lista no ClientHello os protocolos que sabe falar, e o servidor escolhe um deles na resposta, sem viagens extras pela rede [28]. O HTTP/2, por exemplo, se identifica pela sequência h2 [29]. No TLS 1.3, a escolha do servidor viaja na mensagem EncryptedExtensions, que já vai cifrada [2].

O HTTP/2 aproveitou a negociação para impor exigências ao próprio TLS. A RFC 9113, de junho de 2022, pede o TLS 1.2 ou superior, exige que o cliente envie o nome do servidor na SNI e, nas conexões em TLS 1.2, manda desligar a compressão e a renegociação, dois recursos que aparecem na lista de ataques mais adiante; ela também traz uma lista de suítes de cifras que as implantações devem evitar e exige o suporte à TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 com a curva P-256, para que cliente e servidor sempre tenham ao menos uma suíte em comum [29]. Na prática, a configuração de TLS de um servidor antigo afeta também a versão do HTTP que ele consegue oferecer, e a saída do curl -v, mostrada mais adiante, inclui o protocolo combinado pela ALPN.

As duas metades do protocolo: handshake e registro

Por dentro, o TLS se divide em duas partes que trabalham em sequência. A Microsoft descreve uma camada com os protocolos de negociação (o handshake, o de troca de especificação de cifra e o de alertas) e, embaixo dela, o protocolo de registro [6].

O protocolo de handshake é a conversa inicial. Nele, cliente e servidor combinam a versão e os algoritmos, o servidor (e às vezes o cliente) prova a identidade e os dois chegam a um segredo compartilhado sem nunca enviá-lo pela rede. Tudo isso acontece antes do primeiro byte da aplicação.

O protocolo de registro é o que carrega todo o resto. Ele recebe os dados da aplicação, divide-os em registros e protege cada um com as chaves que o handshake produziu. A especificação do TLS 1.3 limita cada registro a 2¹⁴ bytes de dados, ou 16 KB, e marca cada um com um tipo: 20 para a troca de especificação de cifra, 21 para alertas, 22 para mensagens de handshake e 23 para dados da aplicação [2]. Uma resposta HTTP de 100 KB, por exemplo, viaja em pelo menos sete registros, cada um com a própria verificação de integridade.

O tamanho dos registros, aliás, diz algo a quem observa a rede, mesmo sem ler o conteúdo. Por isso o TLS 1.3 permite acrescentar enchimento aos registros, para disfarçar o tamanho real dos dados e dificultar a análise de tráfego; quanto enchimento usar, e quando, a especificação deixa a cargo de cada implementação [2].

No TLS 1.2, o registro calculava um código de autenticação de mensagem, o MAC, sobre os dados e depois cifrava o conjunto, a construção chamada de MAC-then-encrypt. Essa ordem se mostrou uma fonte de problemas: os ataques de padding oracle, como o Lucky Thirteen, exploraram justamente a forma como o servidor reagia a registros com enchimento inválido [7]. O TLS 1.3 abandonou a construção e passou a aceitar só cifras AEAD (Authenticated Encryption with Associated Data), que cifram e autenticam numa operação só, sem a brecha entre uma etapa e outra [2].

Os alertas são o jeito de um lado avisar o outro que algo deu errado: um certificado inválido, uma versão que não é aceita, um registro que não passou na verificação. Alguns são fatais e encerram a conexão na hora. É um desses alertas que aparece, traduzido em linguagem humana, quando o navegador diz que "a conexão não é segura".

Criptografia simétrica e assimétrica: por que o TLS usa as duas

O TLS combina dois tipos de criptografia, cada um no papel em que é melhor.

Na criptografia simétrica, a mesma chave cifra e decifra. É rápida e serve bem para grandes volumes de dados. As cifras simétricas recomendadas hoje para o TLS são o AES, no modo GCM, e o ChaCha20, combinado com o autenticador Poly1305 [12]. O problema da criptografia simétrica é a distribuição da chave: as duas pontas precisam ter o mesmo segredo, e mandá-lo pela rede em texto puro anularia tudo.

Na criptografia assimétrica, ou de chave pública, cada lado tem um par de chaves: uma pública, que pode ser distribuída à vontade, e uma privada, que nunca sai do dono. O que uma faz, só a outra desfaz, e não há como calcular a privada a partir da pública com os recursos computacionais existentes. Com isso, é possível combinar segredos e assinar mensagens sem nenhum segredo prévio. O preço é o desempenho: a Internet Society observa que uma chave RSA de 2048 bits oferece segurança aproximadamente equivalente a uma chave simétrica de 112 bits e que as operações assimétricas podem ser até mil vezes mais pesadas que as simétricas de força equivalente [17].

A solução do TLS é híbrida. A criptografia assimétrica entra no handshake, para duas tarefas: autenticar o servidor, por meio de uma assinatura digital verificável com a chave pública do certificado, e combinar um segredo, por meio de uma troca de chaves. Desse segredo saem as chaves simétricas que protegem todo o tráfego da sessão. Quando a sessão termina, essas chaves são descartadas [17].

Duas ferramentas da criptografia completam o quadro. A função de hash transforma uma mensagem de qualquer tamanho num resumo de tamanho fixo, e uma alteração mínima na mensagem muda o resumo por completo; por isso ela detecta adulterações deliberadas, e não só erros acidentais [5]. A assinatura digital é o hash de uma mensagem cifrado com a chave privada de quem assina: qualquer um com a chave pública correspondente confere que a mensagem veio daquele dono e não foi alterada [5]. O TLS usa as duas o tempo todo: hashes para resumir a conversa do handshake e derivar chaves, assinaturas para provar a identidade.

A troca de chaves Diffie-Hellman

A troca de chaves mais importante do TLS moderno é a de Diffie-Hellman, que leva o nome dos dois pesquisadores que a publicaram. A ideia é que cada lado sorteia um número secreto, calcula a partir dele um valor público e envia esse valor ao outro. Combinando o próprio segredo com o valor público recebido, os dois chegam ao mesmo resultado, que ninguém mais consegue calcular só olhando os valores públicos que passaram pela rede.

A variante usada hoje é a de curvas elípticas (ECDHE), que consegue a mesma segurança com números muito menores. A especificação do TLS 1.3 exige que toda implementação suporte a curva secp256r1, também chamada de P-256, e recomenda a X25519 [2]. O "E" no fim de ECDHE quer dizer efêmero: os números secretos são sorteados de novo a cada conexão e jogados fora logo depois. Essa escolha é a base do sigilo das sessões passadas, que aparece mais adiante.

A alternativa antiga era o transporte de chave por RSA: o cliente sorteava o segredo, cifrava com a chave pública RSA do certificado e enviava ao servidor. Funcionava, mas amarrava a segurança de todas as sessões à chave privada do servidor, por anos. O TLS 1.3 removeu essa opção [2], e o OWASP recomenda desativá-la também no TLS 1.2 [12].

Comparação lado a lado do handshake do TLS 1.2, com duas idas e voltas antes dos dados da aplicação, e do TLS 1.3, com uma ida e volta: no 1.3 o cliente já envia a parte dele da troca de chaves no ClientHello, e tudo depois do ServerHello viaja cifrado
O mesmo objetivo em menos tempo: o TLS 1.3 corta uma ida e volta e cifra quase toda a negociação

O handshake do TLS 1.2, passo a passo

Mesmo com o TLS 1.3 em uso amplo, o handshake do TLS 1.2 continua importante: muitos sistemas ainda o negociam, e entender as mensagens dele ajuda a ler logs e diagnosticar falhas. A RFC 5246 descreve a sequência completa [3]:

  1. ClientHello. O cliente abre a conversa com a versão mais alta que aceita, um número aleatório de 32 bytes (o client random), a lista de suítes de cifras que conhece e as extensões que quer usar, como a indicação do nome do servidor [3][5].
  2. ServerHello. O servidor escolhe a versão e a suíte de cifras entre as oferecidas e manda o próprio número aleatório de 32 bytes (o server random) [3][5].
  3. Certificate. O servidor envia a cadeia de certificados, que normalmente termina perto de uma autoridade raiz conhecida [5].
  4. ServerKeyExchange. Nas trocas efêmeras, o servidor envia o valor público dele, assinado com a chave privada do certificado. A assinatura prova que quem negocia é o dono do certificado.
  5. CertificateRequest, opcional. Se o servidor quer autenticar o cliente, pede o certificado dele aqui.
  6. ServerHelloDone. O servidor avisa que terminou a parte dele [5].
  7. ClientKeyExchange. O cliente envia o valor público dele (no Diffie-Hellman) ou o segredo pré-mestre cifrado com a chave pública do servidor (no transporte por RSA) [3][5]. No caso do RSA, esse segredo tem 48 bytes: dois para a versão e 46 sorteados [3].
  8. ChangeCipherSpec e Finished, dos dois lados. Cada um avisa que dali em diante vai cifrar, e envia a primeira mensagem protegida: um resumo de toda a conversa até ali. Se alguém tiver alterado qualquer mensagem do handshake, os resumos não batem e a conexão cai [3][5].

Com os valores trocados, os dois lados calculam o segredo mestre, sempre de 48 bytes, a partir do segredo pré-mestre e dos dois números aleatórios, por uma função pseudoaleatória definida na especificação [3]. Do segredo mestre saem as chaves que cifram e autenticam os registros em cada direção.

O custo dessa sequência é tempo: o cliente só envia o primeiro dado da aplicação depois de duas idas e voltas completas pela rede. Numa conexão com 150 milissegundos de ida e volta, por exemplo, são cerca de 300 milissegundos só de negociação, somados à abertura da conexão TCP.

As suítes de cifras

No TLS 1.2, uma suíte de cifras é um nome que amarra tudo de uma vez. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, por exemplo, quer dizer: troca de chaves ECDHE, autenticação com certificado RSA, cifra AES de 128 bits no modo GCM e SHA-256 na função de derivação. A RFC 5246 exigia que toda implementação soubesse usar a TLS_RSA_WITH_AES_128_CBC_SHA [3], uma combinação que hoje o OWASP manda evitar por usar transporte de chave RSA e modo CBC [12].

Centenas de combinações foram registradas ao longo dos anos, muitas delas fracas: suítes sem cifra nenhuma (as null), sem autenticação (as anônimas) e as de exportação, enfraquecidas de propósito para cumprir regras de exportação dos anos 1990. A recomendação atual é desativar todas elas [12]. O excesso de opções era, por si só, um risco: cada combinação a mais é uma chance a mais de configurar errado.

O handshake do TLS 1.3

O TLS 1.3 reorganizou o handshake em torno de uma aposta: o cliente adivinha qual troca de chaves o servidor vai aceitar e já manda a parte dele logo na primeira mensagem. A RFC 8446 mostra a sequência completa [2]:

  1. ClientHello, com a extensão key_share, que já traz o valor público do cliente para uma ou mais curvas (normalmente a X25519), além das versões e dos algoritmos de assinatura aceitos [2].
  2. ServerHello, com o valor público do servidor. Nesse ponto os dois já conseguem calcular o segredo compartilhado, e tudo o que vem depois viaja cifrado [2].
  3. EncryptedExtensions, Certificate, CertificateVerify (a assinatura sobre toda a conversa até ali, que prova a posse da chave privada) e Finished, todos já protegidos [2].
  4. O cliente confere o certificado e a assinatura, envia o próprio Finished e começa a mandar dados da aplicação.

O resultado é uma ida e volta a menos: o TLS 1.3 entrega os primeiros dados depois de uma única viagem completa, contra duas do TLS 1.2 [4]. E, como o certificado viaja cifrado, quem observa a rede não vê mais qual certificado o servidor apresentou.

Se o palpite do cliente estiver errado, porque o servidor não aceita nenhuma das curvas oferecidas, o servidor responde com um HelloRetryRequest indicando a curva que prefere, e o cliente recomeça. Custa uma ida e volta a mais, e é por isso que os clientes oferecem logo de saída as curvas mais aceitas.

O que o TLS 1.3 tirou

A lista de remoções da RFC 8446 é tão importante quanto a de novidades [2]:

  • As suítes com transporte de chave RSA e com Diffie-Hellman estático foram removidas. Toda troca de chaves por chave pública passou a ser efêmera, com sigilo das sessões passadas garantido.
  • Os algoritmos simétricos antigos foram podados; sobraram só os AEAD.
  • A compressão foi retirada, junto com o algoritmo de assinatura DSA e os grupos Diffie-Hellman personalizados.
  • O mecanismo antigo de renegociação deixou de existir, assim como a retomada por identificador de sessão, substituída por um mecanismo único de chave pré-compartilhada.
  • A derivação de chaves foi redesenhada em torno do HKDF, uma função baseada em HMAC que facilita a análise formal por criptógrafos.

Com menos peças, as suítes de cifras do TLS 1.3 ficaram curtas. Elas só dizem a cifra e o hash, porque a troca de chaves e a autenticação são negociadas à parte. Toda implementação precisa suportar a TLS_AES_128_GCM_SHA256 e deveria suportar a TLS_AES_256_GCM_SHA384 e a TLS_CHACHA20_POLY1305_SHA256 [2].

Por dentro da derivação de chaves

O handshake do TLS 1.3 não produz uma chave, e sim uma sequência delas, cada uma derivada da anterior. A ferramenta é o HKDF, publicado na RFC 5869 em maio de 2010, que trabalha em duas etapas: a extração condensa um material de entrada numa chave pseudoaleatória de tamanho fixo, e a expansão estica essa chave em quantas chaves de saída forem necessárias [27]. A RFC 8446 encadeia essas etapas num cronograma de chaves alimentado por dois materiais, a chave pré-compartilhada da retomada, quando existe, e o segredo da troca (EC)DHE [2]:

  1. Segredo inicial (Early Secret). Sai da extração sobre a chave pré-compartilhada. Dele derivam a chave dos dados antecipados do 0-RTT e a chave que amarra o tíquete de retomada ao handshake em curso [2].
  2. Segredo do handshake (Handshake Secret). Uma nova extração, agora com o segredo da troca de chaves como entrada, produz as chaves que cifram o restante do handshake, uma para cada sentido [2].
  3. Segredo mestre (Master Secret). Uma última extração gera as chaves do tráfego da aplicação, também uma por sentido, a chave usada para exportar material a outros protocolos e a chave de retomada, que dá origem aos tíquetes das próximas conexões [2].

Cada chave derivada recebe, na expansão, um rótulo próprio e o resumo das mensagens do handshake trocadas até aquele ponto [2]. Daí saem duas propriedades. Chaves de etapas e de sentidos diferentes nunca coincidem, mesmo vindas do mesmo segredo, o que impede, por exemplo, que um registro enviado pelo cliente seja refletido de volta como se viesse do servidor. E qualquer alteração numa mensagem do handshake muda o resumo e, com ele, todas as chaves seguintes: a conexão cai em vez de seguir com parâmetros adulterados. No TLS 1.2, o segredo mestre saía de uma única função pseudoaleatória [3]; o desenho em degraus do 1.3 separa o que protege a negociação do que protege os dados e, como diz a própria RFC 8446, foi pensado para facilitar a análise formal [2].

Trocar as chaves no meio da conversa

Uma conexão TLS pode durar horas, como a de um sistema que mantém uma integração aberta o dia todo, e existe um limite para a quantidade de dados que uma mesma chave cifra com segurança. A RFC 8446 calcula que, com o AES-GCM, até 2^24,5 registros de tamanho máximo, cerca de 24 milhões, podem ser cifrados numa conexão mantendo a margem de segurança; com o ChaCha20-Poly1305, o contador de registros daria a volta antes de esse limite chegar [2]. Com registros de até 16 KB, o limite do AES-GCM fica na casa de algumas centenas de gigabytes por conexão.

Para não chegar lá, o TLS 1.3 tem a mensagem KeyUpdate: qualquer um dos lados avisa que passou a cifrar com a geração seguinte de chaves e pode pedir ao outro que faça o mesmo; quem recebe o pedido precisa responder com o próprio KeyUpdate antes do próximo registro de dados da aplicação [2]. A especificação pede que as implementações façam essa troca antes de atingir os limites [2]. As bibliotecas cuidam disso sozinhas, mas conhecer o mecanismo explica por que um registro de depuração mostra mensagens de handshake no meio de uma conexão estabelecida há horas.

A versão disfarçada de 1.2

Um detalhe curioso do TLS 1.3 revela o tamanho do problema de compatibilidade na internet. A mensagem ClientHello do TLS 1.3 declara, no campo de versão tradicional, o número 0x0303, que é o do TLS 1.2; a versão real vai numa extensão nova, a supported_versions, que lista 0x0304 para o TLS 1.3 [2]. O motivo foram os equipamentos intermediários, como firewalls, proxies e balanceadores, que recusavam ou derrubavam conexões com um número de versão que não conheciam. O próprio documento registra que o desenho do TLS 1.3 foi limitado pela grande quantidade dessas caixas fora do padrão em operação [2].

Pelo mesmo motivo, o TLS 1.3 ainda envia uma mensagem ChangeCipherSpec sem função real, só para parecer uma retomada de sessão do TLS 1.2 aos olhos desses equipamentos; é o chamado modo de compatibilidade com intermediários [2].

A proteção contra rebaixamento

Se um atacante no meio do caminho conseguisse apagar a oferta do TLS 1.3 no ClientHello, o servidor responderia com o TLS 1.2, e a conexão perderia as proteções novas sem que ninguém percebesse. Para impedir isso, o servidor com TLS 1.3 que acaba negociando uma versão anterior grava uma marca nos últimos oito bytes do número aleatório: os bytes 44 4F 57 4E 47 52 44, que formam a palavra "DOWNGRD" em ASCII, seguidos de 01 para o TLS 1.2 ou de 00 para versões mais antigas [2]. Como esse número aleatório entra na assinatura do servidor, o atacante não consegue apagar a marca, e um cliente com TLS 1.3 que a encontra encerra a conexão.

Antes do TLS 1.3, a proteção equivalente era o valor TLS_FALLBACK_SCSV, que o cliente incluía ao repetir uma conexão com uma versão mais baixa; o OWASP recomenda mantê-lo ativo onde versões antigas ainda são aceitas [12].

Certificados e a cadeia de confiança

A troca de chaves resolve o segredo, mas não diz com quem o segredo foi combinado. Um atacante no meio do caminho poderia fazer uma troca Diffie-Hellman perfeita com a vítima. Quem resolve esse problema é o certificado.

Um certificado de chave pública é o equivalente digital de um passaporte, compara a documentação da Oracle: ele liga uma chave pública a uma identidade, e é emitido por uma terceira parte confiável, a autoridade certificadora (CA), que confere a identidade do solicitante antes de assinar, como um cartório reconhece uma firma [5]. Os campos principais são o emissor, o período de validade, o titular, a chave pública do titular e a assinatura da CA [5]. O formato usado na internet é o X.509 [17].

Raízes, intermediárias e a cadeia

Nenhum navegador conhece todos os certificados do mundo. Ele conhece um conjunto limitado de certificados raiz, que vêm instalados com o sistema operacional ou com o próprio navegador. A Internet Society aponta que os principais programas de raízes confiáveis são mantidos pela Microsoft, pela Apple e pela Mozilla, e contava cerca de cinquenta autoridades publicamente confiáveis, a maioria com mais de um certificado raiz [17].

A raiz é a âncora de toda a confiança, e por isso é protegida: os certificados dos sites costumam ser assinados por um ou mais certificados intermediários, que por sua vez são assinados pela raiz [17]. Na conexão, o servidor envia o próprio certificado e os intermediários; o cliente monta a cadeia até uma raiz que já conhece e confere cada elo:

  1. A assinatura de cada certificado confere com a chave pública do certificado acima dele.
  2. Todos estão dentro do período de validade.
  3. O nome que o cliente pediu aparece no certificado do servidor.
  4. Nenhum foi revogado e todos têm permissão para o uso que estão fazendo (um certificado de site não pode assinar outros certificados).

Um erro comum de configuração vem daqui: o servidor envia só o próprio certificado, sem os intermediários. Navegadores às vezes contornam o problema, mas sistemas e bibliotecas costumam recusar a conexão, e o erro aparece como "não foi possível verificar a cadeia de certificados".

O nome certo no lugar certo

O item 3 da lista merece atenção. O nome do site precisa estar na extensão Subject Alternative Name (SAN) do certificado; o OWASP lembra que o Chrome moderno ignora o campo antigo de nome comum (CN) [12]. Um único certificado pode trazer vários nomes no SAN, e é assim que um servidor atende exemplo.com.br e www.exemplo.com.br com o mesmo certificado.

Os certificados curinga (*.exemplo.com.br) valem para qualquer subdomínio de um nível. São práticos, mas o OWASP recomenda usá-los só quando realmente necessário e nunca compartilhar o mesmo curinga entre sistemas com níveis de confiança diferentes, porque a chave de um vira a chave de todos [12]. O mesmo documento sugere registros CAA no DNS, que dizem quais autoridades podem emitir certificados para o domínio [12].

DV, OV e EV

Os certificados se dividem pelo rigor da verificação. O de validação de domínio (DV) prova só que o solicitante controla o domínio, e não afirma nenhuma relação com uma empresa. Os de validação de organização (OV) e de validação estendida (EV) acrescentam conferências sobre a existência legal, o endereço e as pessoas por trás do pedido [17]. O OWASP observa que, para o navegador, a validação de domínio é a base, e que OV e EV não acrescentam segurança visível ao usuário [12].

Let's Encrypt, ACME e a validade cada vez menor

Até meados da década de 2010, um certificado custava dinheiro e trabalho manual, e muitos sites ficavam sem HTTPS por isso. O cenário mudou com o Let's Encrypt, autoridade gratuita e automatizada, e com o protocolo ACME, publicado na RFC 8555 em março de 2019, que automatiza a verificação do domínio, a emissão e a revogação de certificados [18]. Um programa como o certbot conversa com a autoridade, prova o controle do domínio e instala o certificado sem intervenção humana.

A automação abriu caminho para certificados de vida curta. Em abril de 2025, o CA/Browser Forum, que reúne autoridades e fabricantes de navegadores, aprovou a redução gradual da validade máxima dos certificados públicos: 200 dias a partir de 15 de março de 2026, 100 dias a partir de 15 de março de 2027 e 47 dias a partir de 15 de março de 2029 [20]. O Let's Encrypt, que emite certificados de 90 dias, anunciou a própria transição: certificados de 64 dias no perfil padrão a partir de fevereiro de 2027 e de 45 dias a partir de fevereiro de 2028 [19]. A recomendação da autoridade é clara: renovar automaticamente, por volta de dois terços da validade, e monitorar para pegar renovações que falharam [19]. Uma rotina fixa de renovação a cada 60 dias, por exemplo, deixa de funcionar com certificados de 45.

O motivo é de segurança: um certificado comprometido ou emitido por engano continua válido até vencer, e a validade curta limita essa janela e obriga a automação.

Diagrama da cadeia de confiança: o certificado do site, com o nome no SAN e a validade, assinado por um certificado intermediário, que por sua vez é assinado por uma autoridade raiz guardada no repositório de confiança do sistema operacional e do navegador; ao lado, as quatro conferências que o cliente faz em cada elo
O navegador não conhece o site: conhece algumas raízes, e confere a cadeia de assinaturas até uma delas

As limitações do modelo

O modelo das autoridades certificadoras tem uma fraqueza estrutural: qualquer autoridade confiável pode emitir um certificado para qualquer domínio, tenha o dono pedido ou não [17]. Por isso uma autoridade comprometida é um problema para toda a internet, e não só para os clientes dela. Uma das respostas foi o DANE, que permite ao dono do domínio publicar no DNS, protegido pelo DNSSEC, as próprias chaves públicas, sem depender só de terceiros [17].

Certificate Transparency: um diário público das emissões

Outra resposta, a que os navegadores de fato adotaram, foi tornar as emissões públicas. A Certificate Transparency (CT), descrita na RFC 6962, de junho de 2013, propõe registros públicos (logs) em que os certificados são anotados ao serem emitidos, para que qualquer pessoa possa auditar o trabalho das autoridades e encontrar certificados suspeitos; a meta declarada no documento é que, com o tempo, os clientes recusem certificados que não aparecem em nenhum registro [30]. A MDN lembra o contexto: a CT nasceu depois de incidentes como a invasão da autoridade holandesa DigiNotar, em 2011 [32].

Os registros são construídos sobre árvores de Merkle, que só aceitam acréscimos e permitem provar com poucos cálculos que um certificado está lá [32]. Ao receber um certificado, o registro devolve um carimbo de tempo assinado (SCT), a promessa de que ele será incluído. O SCT chega ao navegador por três caminhos: embutido no próprio certificado pela autoridade, o caso mais comum; numa extensão do TLS durante o handshake; ou dentro da resposta de OCSP grampeada, descrita na próxima seção [32]. O Chrome e o Safari exigem SCTs válidos para confiar em certificados públicos, e o Firefox passou a exigir a inclusão nos registros a partir da versão 135, no computador, e da 145, no Android [32]. A versão 2.0 do protocolo, publicada na RFC 9162 em 2021, substituiu a RFC 6962 [31].

Para o dono de um domínio, a CT tem um uso prático: os registros são públicos e podem ser consultados, e um certificado emitido para o seu domínio sem que a equipe tenha pedido é sinal de problema. Somada aos registros CAA no DNS, que dizem quais autoridades podem emitir para o domínio [12], ela reduz bastante a brecha descrita acima.

Revogação: quando o certificado precisa deixar de valer antes da hora

Um certificado tem data de validade, mas às vezes precisa perder a confiança antes dela: a chave privada vazou, o domínio mudou de dono, a autoridade emitiu por engano. A revogação existe para isso, e o cliente precisa de um jeito de descobrir que um certificado ainda dentro do prazo não merece mais confiança.

O caminho mais antigo são as listas de certificados revogados (CRL), que a autoridade publica periodicamente e o cliente baixa para consultar. O OCSP (Online Certificate Status Protocol), cuja especificação atual é a RFC 6960, de junho de 2013, nasceu como alternativa às listas: em vez de baixar tudo, o cliente pergunta a um servidor da autoridade qual é a situação de um certificado específico [33]. A consulta resolve o tamanho das listas, mas cria dois problemas: acrescenta uma viagem pela rede a uma conexão nova e conta à autoridade quais sites cada pessoa está visitando.

O grampeamento do OCSP (OCSP stapling) tentou corrigir os dois. O próprio servidor consulta a autoridade de tempos em tempos e entrega a resposta assinada junto com o certificado; o cliente pede isso pela extensão status_request, definida na RFC 6066 [15]. No TLS 1.3, a resposta viaja dentro da entrada do certificado na mensagem Certificate, e não numa mensagem separada, como no TLS 1.2 [2].

A tendência recente, porém, é a volta das listas. Em dezembro de 2024, o Let's Encrypt anunciou o fim do OCSP: incluiu os endereços das CRL nos certificados, retirou os endereços de OCSP deles em 7 de maio de 2025 e desligou os servidores de OCSP em 6 de agosto de 2025 [34]. O motivo principal declarado foi a privacidade: quem opera o OCSP fica sabendo quais sites um endereço IP está consultando, uma informação que uma autoridade poderia ser obrigada por lei a guardar, e as CRL não têm esse problema; a autoridade citou também o custo de manter o serviço [34]. A validade cada vez menor dos certificados, descrita acima, trabalha na mesma direção: quanto mais curta a vida de um certificado, menor a janela em que um certificado comprometido continua valendo.

Sigilo das sessões passadas

Imagine que alguém grave, hoje, todo o tráfego cifrado entre uma empresa e o banco dela, sem conseguir ler nada. Daqui a três anos, por um vazamento ou uma invasão, a chave privada do certificado do banco cai nas mãos dessa pessoa. O que acontece com as gravações?

Depende da troca de chaves. Com o transporte de chave por RSA do TLS 1.2, o segredo de cada sessão viajou cifrado com a chave pública do servidor. Com a chave privada em mãos, o atacante decifra o segredo de cada sessão gravada e, a partir dele, todo o tráfego. A RFC 7457 registra exatamente esse risco: chaves privadas roubadas permitem decifrar sessões passadas e futuras quando não há sigilo das sessões passadas [7].

Com a troca efêmera (ECDHE ou DHE), o cenário é outro. A chave privada do certificado só assinou a negociação; ela não participou do cálculo do segredo, que veio de números sorteados na hora e descartados em seguida. Quem rouba a chave privada consegue se passar pelo servidor dali em diante, mas não consegue decifrar o que já foi gravado [4]. Essa propriedade se chama forward secrecy, ou sigilo das sessões passadas (às vezes "sigilo antecipado" ou "segredo direto", em traduções mais literais).

O TLS 1.3 tornou o sigilo das sessões passadas obrigatório ao remover as trocas estáticas [2]. No TLS 1.2, ele depende da configuração: o servidor precisa preferir as suítes ECDHE e recusar as de transporte RSA, como recomenda o OWASP [12]. A RFC 9846 foi um passo além e proibiu reaproveitar o mesmo valor da troca de chaves entre conexões diferentes [1], uma prática que algumas implementações adotavam para economizar processamento e que enfraquecia exatamente essa propriedade.

Retomada de sessão e 0-RTT

O handshake completo custa tempo e processamento, e clientes que se reconectam com frequência ao mesmo servidor pagariam esse custo toda vez. A retomada de sessão existe para isso: o cliente que já negociou com o servidor apresenta uma prova da sessão anterior e pula a parte cara. A Microsoft lista os ganhos: menos uso de recursos no servidor, menos banda e menos tempo de handshake [6].

No TLS 1.2 havia dois mecanismos. No mais antigo, o servidor guardava o estado da sessão e entregava ao cliente um identificador; no mais novo, os tíquetes de sessão da RFC 5077, o servidor cifra o estado e entrega ao cliente, que devolve na reconexão, e o servidor não precisa guardar nada [6]. Os tíquetes facilitam a vida de quem tem vários servidores atrás de um balanceador, que conseguem retomar as sessões uns dos outros [6].

O TLS 1.3 substituiu os dois por um único mecanismo de chave pré-compartilhada (PSK): ao fim de uma conexão, o servidor envia um tíquete associado a um segredo derivado da sessão, e o cliente o apresenta na próxima vez [2]. A retomada pode, e deveria, ser combinada com uma nova troca efêmera de chaves, para manter o sigilo das sessões passadas.

O 0-RTT e o risco de repetição

A retomada abre espaço para o recurso mais rápido e mais delicado do TLS 1.3: o 0-RTT, ou dados antecipados. Com um tíquete válido, o cliente pode enviar dados da aplicação já no primeiro voo, junto com o ClientHello, cifrados com a chave da sessão anterior [2]. O servidor processa o pedido sem esperar nenhuma ida e volta.

O preço está escrito na especificação: os dados antecipados não têm garantia contra repetição entre conexões, nem sigilo das sessões passadas [2]. Um atacante que capture o primeiro voo pode reenviá-lo, e o servidor pode processar o mesmo pedido duas vezes. A RFC 8446 descreve defesas no servidor, como tíquetes de uso único, o registro dos ClientHello recebidos e a conferência de que o tíquete é recente, e determina que o cliente só envie como dado antecipado aquilo que pode ser repetido sem dano [2].

Na prática, isso significa limitar o 0-RTT a pedidos que só leem, como carregar uma página. Um pedido que cria um boleto, transfere dinheiro ou grava qualquer coisa não pode ir no 0-RTT, a menos que a aplicação tenha a própria proteção contra duplicidade, como uma chave de idempotência.

Uma história contada por ataques

Quase todas as mudanças do TLS têm um ataque por trás. A RFC 7457, de fevereiro de 2015, reuniu os mais conhecidos até então [7], e a lista ajuda a entender por que a configuração recomendada é a que é.

Diagrama de um registro do TLS 1.3: os dados da aplicação são divididos em pedaços de até 16 KB, cada pedaço recebe o tipo verdadeiro e um enchimento opcional, passa por uma cifra AEAD que cifra e autentica ao mesmo tempo, e sai com um cabeçalho externo de tipo 23, versão 0x0303 e o comprimento, seguido do texto cifrado e da etiqueta de autenticação
Um registro do TLS 1.3 por dentro: cifrar e autenticar numa operação só fechou a porta dos ataques de enchimento
  • Renegociação (2009). Uma falha no próprio desenho do protocolo permitia que um atacante emendasse comandos dele no início de uma conexão legítima. Afetava todas as versões da época e foi corrigida por uma extensão, a RFC 5746 [7].
  • BEAST (2011). Explorava o vetor de inicialização previsível do modo CBC no TLS 1.0 para decifrar partes do tráfego, como cookies HTTP [7]. O TLS 1.1 já havia corrigido o problema no protocolo, mas quase ninguém o usava.
  • CRIME (2012). Mostrou que a compressão no nível do TLS vaza informação: comparando o tamanho dos registros comprimidos, um atacante conseguia descobrir cookies de sessão [7]. A resposta foi desligar a compressão, e o TLS 1.3 nem oferece mais esse recurso [12]. Variações como o TIME e o BREACH atacam a compressão no HTTP, e a defesa precisa ser feita na aplicação [7].
  • Lucky Thirteen (2013). Um ataque de tempo contra o enchimento do modo CBC: medindo quanto o servidor demorava para rejeitar registros adulterados, era possível recuperar texto cifrado [7].
  • RC4 (2013). Estudos mostraram vieses na sequência gerada pela cifra RC4, suficientes para recuperar textos cifrados repetidamente [7]. Em 2015, a RFC 7465 proibiu o RC4 em todas as versões do TLS [9].
  • Heartbleed (2014). Não era uma falha do protocolo, mas de uma implementação: um erro de programação na extensão heartbeat do OpenSSL, das versões 1.0.1 a 1.0.1f, deixava qualquer pessoa ler pedaços da memória do servidor. Divulgado em 7 de abril de 2014 e corrigido na versão 1.0.1g, o defeito expunha chaves privadas de certificados, nomes de usuários, senhas e o conteúdo protegido [11]. Mostrou que a biblioteca é tão importante quanto o protocolo.
  • POODLE (2014). Um ataque de padding oracle contra o SSL 3.0, sem mitigação conhecida [7]. Funcionava porque clientes e servidores aceitavam cair para o SSL 3.0 quando a negociação mais moderna falhava. Selou o fim do SSL 3.0, proibido em 2015 [10].
  • Triple handshake (2014). Permitia que duas conexões diferentes compartilhassem o mesmo material de chaves, abrindo caminho para ataques no meio do caminho [7].
  • SSL stripping. Não ataca a criptografia: ataca a ausência dela. O atacante intercepta a primeira requisição em HTTP puro e impede o redirecionamento para o HTTPS, mantendo a vítima numa conexão sem proteção [7][13]. A defesa é o HSTS, assunto da próxima seção.

O padrão se repete: recursos opcionais e pouco usados, como a compressão, a renegociação e o heartbeat, viraram portas de entrada, e a compatibilidade com versões antigas abriu caminho para o rebaixamento. O TLS 1.3 é, em boa parte, a soma dessas lições.

O fim do TLS 1.0 e do 1.1

A RFC 8996, de 2021, aposentou o TLS 1.0 e o 1.1 [8]. Os motivos que ela aponta são técnicos: a integridade do handshake depende de um resumo SHA-1 contínuo, o que abre caminho para ataques de rebaixamento e fica bem abaixo da margem de segurança aceitável hoje; as assinaturas usam SHA-1 ou uma combinação de MD5 com SHA-1; e as versões antigas não suportam as cifras AEAD recomendadas [8]. O documento acrescenta um argumento prático: manter quatro versões do protocolo aumenta a chance de configurar errado [8].

No Brasil, o Serpro, empresa de tecnologia do governo federal, desligou o TLS 1.0 e o 1.1 no gateway das próprias APIs em 26 de janeiro de 2026 e avisou que os clientes que continuassem nessas versões deixariam de conseguir se integrar aos serviços [21]. O comunicado citava o ataque BEAST e os algoritmos fracos, como o MD5 e o SHA-1, que favorecem ataques do tipo SLOTH, e recomendava planejar desde logo a migração para o TLS 1.3 [21]. É o tipo de mudança que chega a toda empresa que integra sistemas: um servidor antigo, uma versão desatualizada do Java ou do .NET, uma biblioteca esquecida num serviço legado, e a integração para de funcionar no dia marcado.

Configurar bem: o que as recomendações dizem

A maior parte das conexões inseguras não vem de falhas no protocolo, e sim de configurações antigas. A folha de recomendações do OWASP sobre TLS reúne o que vale hoje [12]:

Versões. TLS 1.3 por padrão e TLS 1.2 para compatibilidade. TLS 1.0 e 1.1 desligados, como pedem a RFC 8996, o PCI DSS e a publicação 800-52 do NIST; SSL 2.0 e 3.0 sempre desligados [12]. Se clientes antigos precisarem ser atendidos, o OWASP sugere separá-los num endereço próprio, sem acesso a dados sensíveis [12].

Cifras. No TLS 1.3, as suítes AEAD padrão (AES-GCM ou ChaCha20-Poly1305). No TLS 1.2, preferir AEAD e ECDHE, evitar o modo CBC e desativar as suítes nulas, anônimas, de exportação, de transporte de chave RSA e de Diffie-Hellman estático [12].

Grupos de troca de chaves. As curvas x25519, prime256v1 (a P-256), x448 e secp384r1, os grupos de campo finito a partir de ffdhe2048 e, para a proteção pós-quântica, o X25519MLKEM768 [12].

Certificados. Chave RSA de pelo menos 2048 bits, assinatura com SHA-256 e todos os nomes no SAN [12]. A chave privada protegida por permissões de arquivo, sem cópias espalhadas. Nada de nomes internos ou endereços IP em certificados públicos [12].

Bibliotecas. Mantidas atualizadas, porque o Heartbleed mostrou que uma falha na implementação anula qualquer configuração [12].

Teste. Ferramentas online como o SSL Labs e ferramentas locais como o testssl.sh e o SSLyze mostram as versões, as cifras e os problemas de um servidor [12]. Para escrever a configuração, a Mozilla mantém um gerador que produz arquivos prontos para o nginx, o Apache e outros servidores, em perfis moderno, intermediário e antigo [13][26].

Um trecho de configuração do nginx no espírito dessas recomendações, com TLS 1.2 e 1.3:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name exemplo.com.br www.exemplo.com.br;

    ssl_certificate     /etc/letsencrypt/live/exemplo.com.br/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/exemplo.com.br/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers off;

    add_header Strict-Transport-Security "max-age=63072000" always;
}

server {
    listen 80;
    listen [::]:80;
    server_name exemplo.com.br www.exemplo.com.br;
    return 301 https://$host$request_uri;
}

O arquivo fullchain.pem já traz o certificado e os intermediários, o que evita o erro da cadeia incompleta. A lista de cifras vale só para o TLS 1.2; as do TLS 1.3 são as padrão da biblioteca. E o bloco da porta 80 existe só para redirecionar: o OWASP considera aceitável um redirecionamento permanente para o HTTPS em sites, mas recomenda que APIs recusem o HTTP puro em vez de redirecionar [12], já que um programa que mandou uma credencial em HTTP já a expôs antes de receber o redirecionamento.

HSTS: HTTPS sempre, desde a próxima visita

O redirecionamento da porta 80 tem uma fraqueza: a primeira requisição, em HTTP puro, pode ser interceptada, e o atacante simplesmente não repassa o redirecionamento. É o SSL stripping [13]. O HSTS (HTTP Strict Transport Security), definido na RFC 6797 em novembro de 2012, permite que o site declare que só deve ser acessado por conexões seguras [14]. O servidor envia o cabeçalho Strict-Transport-Security, e o navegador passa a usar HTTPS direto em todas as visitas seguintes, mesmo que alguém digite http:// [13].

A proteção tem uma brecha: a primeira visita, ou a primeira depois que o registro do HSTS expira no navegador [13]. Para fechá-la, o Chrome mantém a lista de pré-carga do HSTS, com domínios que o navegador sempre acessa por HTTPS, como se já tivesse recebido o cabeçalho; o Safari e o Firefox usam listas derivadas dela [13].

Conteúdo misto e cookies

O HTTPS da página principal não basta se a página carrega scripts, estilos ou imagens por HTTP. Esse conteúdo misto é inseguro porque os sub-recursos não têm a proteção do HTTPS, e um atacante pode lê-los e alterá-los; os navegadores bloqueiam esses carregamentos ou os convertem para HTTPS [13]. O OWASP completa: usar TLS em todas as páginas, e não só no login, marcar todos os cookies com o atributo Secure, de preferência com o prefixo __Secure-, e usar Cache-Control: no-store em respostas sensíveis [12].

Ver o TLS funcionando

Boa parte dos problemas de TLS se resolve olhando a conexão de perto. Três ferramentas de linha de comando cobrem quase tudo.

O openssl s_client abre uma conexão TLS e mostra a negociação:

openssl s_client -connect exemplo.com.br:443 -servername exemplo.com.br </dev/null

A saída traz a cadeia de certificados enviada pelo servidor, a versão negociada, a suíte escolhida e o resultado da verificação (Verify return code: 0 (ok) quando tudo confere). O -servername envia o nome no ClientHello; sem ele, o servidor pode responder com o certificado padrão, que talvez não seja o do site.

Para ver só os dados do certificado, como os nomes, o emissor e as datas de validade:

openssl s_client -connect exemplo.com.br:443 -servername exemplo.com.br </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates -ext subjectAltName

Para testar se o servidor aceita uma versão específica, os parâmetros -tls1_2 e -tls1_3 forçam a versão:

openssl s_client -connect exemplo.com.br:443 -servername exemplo.com.br -tls1_2 </dev/null

O curl com -v mostra a resolução do nome, a conexão, o handshake e os cabeçalhos numa tela só, e diz exatamente em que etapa falhou:

curl -v https://exemplo.com.br/ -o /dev/null

Um certificado vencido, um nome que não confere ou uma cadeia incompleta aparecem com mensagens diretas. A tentação de usar -k (ou --insecure), que desliga a verificação, deve ficar restrita a testes locais: em produção, desligar a verificação anula a autenticação e deixa a conexão aberta a qualquer um no meio do caminho.

Para uma auditoria completa, o testssl.sh e o SSL Labs varrem todas as versões e cifras aceitas e apontam as fracas [12].

Erros comuns

  • Certificado vencido. O erro mais frequente e o mais evitável. Renovação automática com monitoramento resolve; renovação manual, com validade cada vez menor, é um convite ao incidente [19].
  • Cadeia incompleta. O servidor envia o certificado sem os intermediários. Funciona em alguns navegadores e falha em sistemas e bibliotecas. Use o arquivo com a cadeia completa.
  • Nome que não confere. O certificado não inclui o nome acessado no SAN, ou o servidor entrega o certificado de outro site porque recebeu a conexão no bloco errado.
  • Versão ou cifra antiga. Um sistema legado que só fala TLS 1.0 deixa de conectar quando o outro lado desliga a versão, como aconteceu com as integrações do Serpro [21].
  • Verificação desligada no código. Opções como rejectUnauthorized: false no Node.js ou verify=False no Python, deixadas depois de um teste, transformam a conexão segura numa conexão só cifrada, sem saber com quem.
  • Chave privada exposta. Arquivos .key, .pem e .pfx em repositórios, e-mails ou pastas compartilhadas. A chave do certificado é a identidade do servidor.

TLS mútuo: quando o cliente também mostra o certificado

No uso comum do HTTPS, só o servidor apresenta certificado; o cliente se identifica depois, com senha, token ou cookie, dentro da conexão já cifrada. No TLS mútuo (mTLS), o servidor pede um certificado também ao cliente, com a mensagem CertificateRequest, e o cliente prova que tem a chave privada correspondente com uma assinatura sobre o handshake. O OWASP explica que, no TLS 1.3, essa assinatura amarra a prova àquela conexão específica, o que impede que ela seja reaproveitada em outra [12].

O mTLS é comum onde os dois lados são sistemas, e não pessoas: APIs entre empresas, serviços internos e, principalmente, integrações bancárias. Bancos costumam exigir que a empresa cliente apresente um certificado digital para usar as APIs de cobrança, de Pix e de pagamentos, somado a credenciais de OAuth. Assim, mesmo que o token vaze, ele não serve sem o certificado e a chave privada.

O OWASP aponta os cuidados: o mTLS não dispensa a verificação do certificado do servidor, porque um cliente que aceita um servidor falso entrega os dados do mesmo jeito; a gestão dos certificados de cliente dá trabalho; e equipamentos que inspecionam o tráfego TLS no meio do caminho quebram a autenticação do cliente [12]. Por isso a recomendação é usar o mTLS em aplicações e APIs de alto valor, com usuários técnicos ou internos [12].

O TLS 1.3 acrescentou uma variação: a autenticação depois do handshake. Se o cliente avisou que aceita, o servidor pode pedir o certificado dele a qualquer momento depois que a conexão estiver estabelecida; o cliente responde com o certificado, a assinatura e o Finished, ou com um certificado vazio, se não quiser se identificar [2]. Isso permite, por exemplo, pedir o certificado só quando a pessoa entra numa área restrita, sem exigi-lo de quem só visita as páginas públicas.

Em código, o certificado do cliente costuma ser um arquivo PKCS#12 (.pfx ou .p12), que guarda o certificado e a chave privada protegidos por senha. Um exemplo em Node.js, com a senha vinda do ambiente e nunca escrita no código:

import https from 'node:https';
import fs from 'node:fs';

const opcoes = {
  hostname: 'api.banco.exemplo',
  path: '/cobranca/v1/boletos',
  method: 'GET',
  pfx: fs.readFileSync('/caminho/seguro/empresa.pfx'),
  passphrase: process.env.CERTIFICADO_SENHA,
  minVersion: 'TLSv1.2',
  headers: { Authorization: `Bearer ${process.env.TOKEN_DO_BANCO}` },
};

https
  .request(opcoes, (resposta) => {
    console.log(resposta.statusCode);
    resposta.resume();
  })
  .on('error', console.error)
  .end();

O ponto principal do exemplo está nas opções: o certificado e a chave vêm do arquivo .pfx, a senha vem do ambiente, a versão mínima fica no TLS 1.2 e o token do OAuth vai no cabeçalho, dentro da conexão já autenticada nos dois sentidos. A verificação do certificado do banco continua ligada, que é o padrão.

O TLS e a computação quântica

A troca de chaves por curvas elípticas e as assinaturas RSA e ECDSA dependem de problemas matemáticos que um computador quântico grande o bastante conseguiria resolver. Esse computador ainda não existe, mas o risco já é atual por causa de uma estratégia de ataque conhecida como "guardar agora, decifrar depois": um adversário grava hoje o tráfego cifrado e espera ter a máquina para decifrá-lo. O Google descreveu essa ameaça como relativamente urgente justamente porque não importa quando o computador quântico ficará pronto; o que é gravado hoje já está exposto [24].

As assinaturas dos certificados são um problema menos urgente: forjar uma assinatura no futuro não engana uma conexão que já aconteceu. O que precisa de proteção desde já é a troca de chaves, porque é dela que vem o sigilo do tráfego gravado.

A resposta veio em etapas. Em 13 de agosto de 2024, o NIST, o instituto de padrões dos Estados Unidos, publicou o padrão FIPS 203, que define o ML-KEM (Module-Lattice-Based Key-Encapsulation Mechanism), um mecanismo de encapsulamento de chaves baseado em reticulados, em três níveis de parâmetros: ML-KEM-512, 768 e 1024 [23]. No TLS, ele entrou de forma híbrida: a troca combina a X25519 clássica com o ML-KEM-768, no grupo chamado X25519MLKEM768. Se um dos dois algoritmos for quebrado, o outro continua protegendo o segredo.

Os navegadores adotaram a troca híbrida rapidamente. O Chrome ligou por padrão uma versão preliminar, baseada no Kyber, o algoritmo que deu origem ao ML-KEM, em todas as plataformas de computador a partir da versão 124, em 2024; a implantação revelou defeitos em vários equipamentos intermediários de TLS, e o Google ofereceu uma política temporária para empresas desligarem o recurso enquanto os fabricantes corrigiam os produtos [24]. Segundo a Cloudflare, o Firefox habilitou a troca pós-quântica no computador em novembro de 2024, o Chrome no Android no mesmo mês, e a Apple a incluiu por padrão nos sistemas da versão 26, em outubro de 2025; no fim de outubro de 2025, mais da metade do tráfego humano que passava pela rede da Cloudflare já estava protegido contra o "guardar agora, decifrar depois" [25]. O OWASP já lista o X25519MLKEM768 entre os grupos recomendados [12].

O TLS 1.3 acomodou a mudança sem versão nova, porque a troca de chaves é negociada por grupos: o grupo híbrido é só mais uma opção no key_share. A RFC 9846 generalizou o texto da especificação para descrever trocas por encapsulamento de chaves, e não só por Diffie-Hellman [1]. A consequência prática é o tamanho: as chaves do ML-KEM são bem maiores que as da X25519, e o ClientHello cresce. Foi por isso que equipamentos intermediários que supunham um ClientHello pequeno quebraram na implantação [24].

Do lado do servidor, a proteção depende da biblioteca de TLS: um servidor que não conhece o grupo híbrido escolhe outro grupo oferecido pelo cliente, e a conexão funciona, só que sem a proteção pós-quântica. Manter a biblioteca atualizada é, de novo, a principal providência.

Privacidade: o nome que ainda vaza

Mesmo com o TLS 1.3 cifrando o certificado, uma informação continua visível a quem observa a rede: o nome do site. Ele vai em texto puro no ClientHello, na extensão SNI (Server Name Indication), definida na RFC 6066 em 2011 [15]. A SNI existe por um bom motivo: um servidor que atende vários domínios no mesmo endereço IP precisa saber qual certificado apresentar antes de cifrar qualquer coisa, e a SNI permite hospedar vários sites com HTTPS na mesma combinação de IP e porta [6][15].

Para fechar essa brecha, a IETF publicou em 2026 o Encrypted Client Hello (ECH), na RFC 9849, que cifra o ClientHello com uma chave pública do servidor [16]. É um passo recente, e a adoção depende de navegadores, servidores e provedores de DNS.

Como usamos o TLS na Gothor

Todo o tráfego dos serviços da Gothor viaja com TLS, com certificados renovados automaticamente e versões antigas desligadas. Nas integrações bancárias, a autenticação vale nos dois sentidos: os bancos exigem mTLS e OAuth, e a GothorPay cuida disso para que quem integra não precise lidar com o protocolo de cada instituição. Certificados digitais e chaves privadas são tratados como os segredos mais importantes da empresa.

Conclusão

O TLS combina confidencialidade, integridade e autenticação com uma divisão clara de trabalho: a criptografia assimétrica autentica e combina o segredo no handshake, e a simétrica protege o tráfego no registro. O TLS 1.3 reúne três décadas de lições num protocolo mais simples, mais rápido e mais privado, e o ecossistema ao redor seguiu o mesmo caminho: certificados automáticos e de vida curta, HSTS e, agora, a troca de chaves híbrida contra o computador quântico.

Para a operação de uma empresa, as providências cabem numa lista curta: TLS 1.2 e 1.3, e nada abaixo disso; renovação automática de certificados, com monitoramento; bibliotecas e sistemas atualizados; verificação de certificados sempre ligada no código; chaves privadas e certificados de cliente guardados como as senhas mais importantes da empresa. Se a sua empresa integra o Winthor com bancos e quer essa camada cuidada por quem lida com ela todos os dias, fale com a nossa equipe.

Fontes

  1. RFC 9846: The Transport Layer Security (TLS) Protocol Version 1.3 — rfc-editor.org
  2. RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3 — rfc-editor.org
  3. RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2 — rfc-editor.org
  4. Transport Layer Security – Wikipédia, a enciclopédia livre — pt.wikipedia.org
  5. Transport Layer Security (TLS) Protocol Overview — docs.oracle.com
  6. Transport Layer Security protocol — learn.microsoft.com
  7. RFC 7457: Summarizing Known Attacks on Transport Layer Security (TLS) and Datagram TLS (DTLS) — rfc-editor.org
  8. RFC 8996: Deprecating TLS 1.0 and TLS 1.1 — rfc-editor.org
  9. RFC 7465: Prohibiting RC4 Cipher Suites — rfc-editor.org
  10. RFC 7568: Deprecating Secure Sockets Layer Version 3.0 — rfc-editor.org
  11. The Heartbleed Bug — heartbleed.com
  12. Transport Layer Security - OWASP Cheat Sheet Series — cheatsheetseries.owasp.org
  13. Transport Layer Security (TLS) - Security | MDN — developer.mozilla.org
  14. RFC 6797: HTTP Strict Transport Security (HSTS) — rfc-editor.org
  15. RFC 6066: Transport Layer Security (TLS) Extensions: Extension Definitions — rfc-editor.org
  16. RFC 9849: TLS Encrypted Client Hello — rfc-editor.org
  17. What is TLS & How Does it Work? - Internet Society — internetsociety.org
  18. RFC 8555: Automatic Certificate Management Environment (ACME) — rfc-editor.org
  19. Decreasing Certificate Lifetimes to 45 Days — letsencrypt.org
  20. Baseline Requirements for TLS Server Certificates — cabforum.org
  21. Desligamento protocolos TLS 1.0 e 1.1 - Central de Ajuda — centraldeajuda.serpro.gov.br
  22. RFC 9001: Using TLS to Secure QUIC — rfc-editor.org
  23. FIPS 203: Module-Lattice-Based Key-Encapsulation Mechanism Standard — csrc.nist.gov
  24. Advancing our amazing bet on asymmetric cryptography — blog.google
  25. State of the post-quantum Internet in 2025 — blog.cloudflare.com
  26. Mozilla SSL Configuration Generator — ssl-config.mozilla.org
  27. RFC 5869: HMAC-based Extract-and-Expand Key Derivation Function (HKDF) — rfc-editor.org
  28. RFC 7301: Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension — rfc-editor.org
  29. RFC 9113: HTTP/2 — rfc-editor.org
  30. RFC 6962: Certificate Transparency — rfc-editor.org
  31. RFC 9162: Certificate Transparency Version 2.0 — rfc-editor.org
  32. Certificate Transparency - Security | MDN — developer.mozilla.org
  33. RFC 6960: X.509 Internet Public Key Infrastructure Online Certificate Status Protocol - OCSP — rfc-editor.org
  34. Ending OCSP Support in 2025 — letsencrypt.org

Este post foi escrito com a ajuda da Juniper, a assistente de IA da Gothor, e revisado pela nossa equipe antes de ir ao ar.

Comentários

Ainda não há comentários. Que tal ser o primeiro?

Entre na sua conta para comentar. É grátis.

Receba os próximos posts por e-mail

Um e-mail a cada post novo, sem spam. Você cancela quando quiser.

Para ampliar, use a roda do mouse, os botões, as teclas + e − ou o gesto de pinça; toque duas vezes para ampliar ou voltar. Com a imagem ampliada, arraste ou use as setas para mover. Esc fecha.