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.

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].

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].

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]:
- 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].
- 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].
- Certificate. O servidor envia a cadeia de certificados, que normalmente termina perto de uma autoridade raiz conhecida [5].
- 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.
- CertificateRequest, opcional. Se o servidor quer autenticar o cliente, pede o certificado dele aqui.
- ServerHelloDone. O servidor avisa que terminou a parte dele [5].
- 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].
- 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]:
- 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]. - 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].
- EncryptedExtensions, Certificate, CertificateVerify (a assinatura sobre toda a conversa até ali, que prova a posse da chave privada) e Finished, todos já protegidos [2].
- 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]:
- 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].
- 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].
- 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:
- A assinatura de cada certificado confere com a chave pública do certificado acima dele.
- Todos estão dentro do período de validade.
- O nome que o cliente pediu aparece no certificado do servidor.
- 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.

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 é.

- 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: falseno Node.js ouverify=Falseno 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,.peme.pfxem 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
- RFC 9846: The Transport Layer Security (TLS) Protocol Version 1.3 — rfc-editor.org
- RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3 — rfc-editor.org
- RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2 — rfc-editor.org
- Transport Layer Security – Wikipédia, a enciclopédia livre — pt.wikipedia.org
- Transport Layer Security (TLS) Protocol Overview — docs.oracle.com
- Transport Layer Security protocol — learn.microsoft.com
- RFC 7457: Summarizing Known Attacks on Transport Layer Security (TLS) and Datagram TLS (DTLS) — rfc-editor.org
- RFC 8996: Deprecating TLS 1.0 and TLS 1.1 — rfc-editor.org
- RFC 7465: Prohibiting RC4 Cipher Suites — rfc-editor.org
- RFC 7568: Deprecating Secure Sockets Layer Version 3.0 — rfc-editor.org
- The Heartbleed Bug — heartbleed.com
- Transport Layer Security - OWASP Cheat Sheet Series — cheatsheetseries.owasp.org
- Transport Layer Security (TLS) - Security | MDN — developer.mozilla.org
- RFC 6797: HTTP Strict Transport Security (HSTS) — rfc-editor.org
- RFC 6066: Transport Layer Security (TLS) Extensions: Extension Definitions — rfc-editor.org
- RFC 9849: TLS Encrypted Client Hello — rfc-editor.org
- What is TLS & How Does it Work? - Internet Society — internetsociety.org
- RFC 8555: Automatic Certificate Management Environment (ACME) — rfc-editor.org
- Decreasing Certificate Lifetimes to 45 Days — letsencrypt.org
- Baseline Requirements for TLS Server Certificates — cabforum.org
- Desligamento protocolos TLS 1.0 e 1.1 - Central de Ajuda — centraldeajuda.serpro.gov.br
- RFC 9001: Using TLS to Secure QUIC — rfc-editor.org
- FIPS 203: Module-Lattice-Based Key-Encapsulation Mechanism Standard — csrc.nist.gov
- Advancing our amazing bet on asymmetric cryptography — blog.google
- State of the post-quantum Internet in 2025 — blog.cloudflare.com
- Mozilla SSL Configuration Generator — ssl-config.mozilla.org
- RFC 5869: HMAC-based Extract-and-Expand Key Derivation Function (HKDF) — rfc-editor.org
- RFC 7301: Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension — rfc-editor.org
- RFC 9113: HTTP/2 — rfc-editor.org
- RFC 6962: Certificate Transparency — rfc-editor.org
- RFC 9162: Certificate Transparency Version 2.0 — rfc-editor.org
- Certificate Transparency - Security | MDN — developer.mozilla.org
- RFC 6960: X.509 Internet Public Key Infrastructure Online Certificate Status Protocol - OCSP — rfc-editor.org
- 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.


