Como HTTPS e TLS realmente funcionam: um guia prático
Por que HTTPS é importante e o que ele realmente faz
Você provavelmente já viu o ícone de cadeado no seu navegador e assumiu que sua conexão é segura. Mas o que esse cadeado realmente garante? HTTPS (Hypertext Transfer Protocol Secure) é o HTTP sobreposto ao TLS (Transport Layer Security). Ele fornece três garantias principais: confidencialidade (espiões não podem ler os dados), integridade (os dados não podem ser modificados em trânsito sem detecção) e autenticação (você está falando com o servidor real, não com um impostor).
Sem HTTPS, qualquer pessoa no caminho da rede—Wi-Fi de cafeteria, seu provedor de internet ou um roteador malicioso—pode ler ou alterar seu tráfego. Com HTTPS, isso se torna impraticável. Mas o TLS não é mágica; é um protocolo cuidadosamente projetado com etapas específicas. Entender essas etapas ajuda você a depurar problemas de conexão, configurar servidores corretamente e evitar armadilhas comuns.
O handshake TLS: passo a passo
Quando seu navegador se conecta a um site HTTPS, ele realiza um handshake TLS antes de qualquer dado HTTP ser trocado. Aqui está o que acontece em um handshake TLS 1.3 típico (o padrão moderno):
- ClientHello: O cliente envia uma mensagem com versões TLS suportadas, suítes de cifras e um valor aleatório (client random). Também inclui um compartilhamento de chave para troca de chaves (por exemplo, usando ECDHE).
- ServerHello: O servidor responde com a versão TLS escolhida, suíte de cifras, um valor aleatório (server random) e seu próprio compartilhamento de chave. Ele também envia sua cadeia de certificados.
- Verificação do certificado: O cliente valida o certificado do servidor contra CAs raiz confiáveis, verifica o nome do host e garante que não expirou ou foi revogado.
- Derivação de chaves: Ambos os lados calculam o mesmo segredo compartilhado usando suas chaves privadas e os compartilhamentos de chave trocados. A partir disso, derivam chaves de sessão simétricas.
- Finished: Ambos os lados enviam uma mensagem Finished criptografada com as chaves de sessão para verificar a integridade do handshake.
Após o handshake, todos os dados da aplicação (requisições e respostas HTTP) são criptografados com as chaves de sessão simétricas. O TLS 1.3 reduz o handshake para uma ida e volta (1-RTT) e suporta retomada 0-RTT para conexões repetidas, melhorando a latência.
Certificados e cadeias de confiança
Um certificado é um documento digital que vincula uma chave pública a uma identidade (como um nome de domínio). Ele é assinado por uma Autoridade Certificadora (CA). Seu navegador e sistema operacional vêm com um repositório de CAs raiz confiáveis. Quando um servidor apresenta seu certificado, o cliente constrói uma cadeia do certificado do servidor até uma raiz confiável. Se qualquer elo estiver faltando ou for inválido, a conexão falha.
Problemas comuns de certificado incluem:
- Certificado expirado: O período de validade passou.
- Incompatibilidade de nome de host: O certificado é para um domínio diferente (por exemplo,
example.comvswww.example.com). - Cadeia incompleta: O servidor não enviou certificados intermediários, então o cliente não pode construir um caminho até uma raiz confiável.
- Emissor não confiável: O certificado é autoassinado ou de uma CA que não está no repositório de confiança.
Ferramentas como OpenSSL podem ajudar você a inspecionar certificados. Por exemplo, para visualizar a cadeia de certificados que um servidor envia:
openssl s_client -connect example.com:443 -showcerts
Este comando imprime os certificados e o resultado da verificação. Procure por Verify return code: 0 (ok) para confirmar que a cadeia é válida.
Depurando conexões TLS
Quando o HTTPS falha, a mensagem de erro geralmente aponta para a fase que quebrou. Aqui está uma tabela rápida de solução de problemas:
| Sintoma | Causa provável | Ação |
|---|---|---|
| O navegador mostra "certificado expirado" | Certificado passou da data de expiração | Renove o certificado e recarregue o servidor |
| "NET::ERR_CERT_COMMON_NAME_INVALID" | Incompatibilidade de nome de host | Certifique-se de que o certificado cobre o domínio exato (incluindo www, se necessário) |
| "unable to get local issuer certificate" | Certificados intermediários ausentes | Configure o servidor para enviar a cadeia completa |
| O handshake falha com erro de protocolo | Cliente e servidor não têm versão TLS ou cifra em comum | Atualize a configuração do servidor para suportar TLS moderno (1.2+) |
Para uma inspeção mais profunda, use openssl s_client com flags como -tls1_3 para testar versões específicas, ou curl -v https://example.com para ver os detalhes do handshake. As ferramentas de desenvolvedor do navegador (aba Segurança) também mostram informações do certificado e detalhes da conexão.
Melhores práticas para configuração de servidor
A configuração adequada do TLS é crucial para segurança e desempenho. Siga estas diretrizes:
- Use apenas TLS 1.3 e 1.2: Desative versões mais antigas (TLS 1.0, 1.1) que têm vulnerabilidades conhecidas.
- Habilite HTTP/2 ou HTTP/3: Esses protocolos exigem TLS e oferecem benefícios de desempenho.
- Use suítes de cifras fortes: Prefira cifras AEAD como AES-GCM ou ChaCha20-Poly1305.
- Habilite OCSP stapling: Reduz a latência e melhora a privacidade para verificações de revogação.
- Implemente HSTS: O cabeçalho
Strict-Transport-Securitydiz aos navegadores para sempre usar HTTPS para seu domínio. - Automatize a renovação de certificados: Use Let's Encrypt com Certbot ou similar para evitar expiração.
Aqui está um trecho de configuração de exemplo do Nginx para TLS moderno:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/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';
ssl_prefer_server_ciphers off;
add_header Strict-Transport-Security "max-age=63072000" always;
}
Após aplicar as alterações, teste sua configuração com ferramentas como o SSL Test do SSL Labs (online) ou openssl s_client para verificar o handshake e a cadeia de certificados.
Perguntas frequentes
Qual é a diferença entre TLS e SSL?
SSL (Secure Sockets Layer) é o predecessor do TLS. As versões SSL 2.0 e 3.0 estão obsoletas devido a falhas de segurança. TLS 1.2 e 1.3 são os protocolos modernos e seguros. As pessoas costumam dizer "SSL" coloquialmente, mas querem dizer TLS.
Como o HTTPS protege contra ataques man-in-the-middle?
O HTTPS usa certificados assinados por CAs confiáveis para autenticar o servidor. Durante o handshake, o cliente verifica o certificado do servidor e confirma que a chave pública no certificado corresponde à usada na troca de chaves. Isso impede que um atacante se passe pelo servidor sem um certificado válido.
Posso usar HTTPS sem um certificado?
Não. Um certificado é necessário para o servidor provar sua identidade e para o cliente estabelecer um canal criptografado. Você pode usar um certificado autoassinado para testes, mas os navegadores mostrarão um aviso porque não é confiável por CAs públicas. Para produção, use um certificado de uma CA confiável como Let's Encrypt.
Ao trabalhar com configurações de TLS, você pode precisar inspecionar logs do servidor ou testar endpoints. Para uma análise rápida de logs de acesso do Nginx para identificar erros de TLS ou padrões incomuns, experimente o Analisador de Logs Nginx para analisar e visualizar dados de log sem esforço.