Certificados SSL/TLS: como funcionam

1. O Problema da Confiança na Internet

Quando um cliente (navegador, aplicativo) se conecta a um servidor web, os dados trafegam por uma série de roteadores e redes intermediárias. Sem proteção, qualquer nó no caminho pode:

  • Interceptar a comunicação (sniffing de pacotes)
  • Adulterar os dados em trânsito (modificação de conteúdo)
  • Falsificar a identidade do servidor (ataque Man-in-the-Middle)

A criptografia simétrica resolve o sigilo — se ambos os lados compartilham uma chave secreta, os dados ficam ilegíveis para terceiros. Porém, o problema fundamental permanece: como o cliente obtém essa chave secreta com o servidor correto, sem que um atacante se passe por ele?

A resposta está no certificado digital, um documento de identidade eletrônico que vincula uma chave pública à identidade de um servidor.

2. Anatomia de um Certificado Digital

Um certificado X.509 contém campos essenciais:

Campos de um certificado SSL/TLS:
- Subject: CN=exemplo.com.br, O=Empresa Ltda
- Subject Alternative Names (SAN): exemplo.com.br, www.exemplo.com.br
- Issuer: C=US, O=Let's Encrypt, CN=R3
- Validade: Not Before: 2024-01-01, Not After: 2025-01-01
- Chave Pública: algoritmo RSA 2048 bits (ou ECDSA P-256)
- Assinatura Digital: assinatura da CA sobre o hash do certificado
- Serial Number: 04:AB:CD...
- Fingerprint (SHA-256): 2a:3b:4c:...

A assinatura digital funciona assim: a Autoridade Certificadora (CA) calcula o hash de todo o conteúdo do certificado e criptografa esse hash com sua própria chave privada. Qualquer pessoa pode verificar a assinatura usando a chave pública da CA.

A Chain of Trust (cadeia de confiança) é hierárquica:

[Root CA] (autoassinado, pré-instalado no sistema operacional)
    ↓ assina
[Intermediate CA] (emissor intermediário)
    ↓ assina
[Leaf Certificate] (certificado do seu servidor)

O navegador só confia no certificado do servidor se toda a cadeia for válida até uma raiz que ele já conhece.

3. O Handshake TLS Passo a Passo

O handshake TLS 1.3 (simplificado) funciona assim:

Cliente                                  Servidor
   |                                        |
   |--- Client Hello ---------------------->|
   |   (TLS 1.3, cipher suites, random_a)   |
   |                                        |
   |<-- Server Hello -----------------------|
   |   (TLS 1.3, cipher suite escolhida,    |
   |    random_b, certificado do servidor,   |
   |    cadeia de intermediários)            |
   |                                        |
   |<-- Server Key Exchange ----------------|
   |   (parâmetros ECDHE, assinados com     |
   |    chave privada do certificado)       |
   |                                        |
   |   [Cliente verifica:                   |
   |    1. Certificado não expirado         |
   |    2. CA confiável (chain of trust)    |
   |    3. CN/SAN corresponde ao domínio    |
   |    4. Assinatura do Server Hello       |
   |       é válida com a chave pública]    |
   |                                        |
   |--- Client Key Exchange --------------->|
   |   (parâmetros ECDHE do cliente)        |
   |                                        |
   |   [Ambos calculam a chave de sessão    |
   |    usando Diffie-Hellman:              |
   |    chave_sessao = KDF(random_a,        |
   |                    random_b, segredo)  |
   |                                        |
   |--- Finished (criptografado) ---------->|
   |<-- Finished (criptografado) -----------|
   |                                        |
   |   [A partir daqui, toda comunicação    |
   |    é criptografada com AES-GCM usando  |
   |    a chave de sessão]                  |

O uso de ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) garante Perfect Forward Secrecy: mesmo que a chave privada do servidor seja comprometida no futuro, as sessões passadas permanecem seguras.

4. Tipos de Validação e Níveis de Confiança

As CAs oferecem três níveis de validação:

DV (Domain Validation):
  - Verifica apenas: controle sobre o domínio (DNS, email, HTTP)
  - Emissão: automatizada, minutos
  - Custo: geralmente gratuito (Let's Encrypt)
  - Navegador: cadeado cinza, "Conexão segura"
  - Ideal para: blogs, APIs internas, testes

OV (Organization Validation):
  - Verifica: registro legal da empresa, endereço, telefone
  - Emissão: dias a semanas
  - Custo: médio (US$ 50-200/ano)
  - Navegador: cadeado, mostra nome da organização
  - Ideal para: e-commerce, SaaS B2B

EV (Extended Validation):
  - Verifica: processo rigoroso, presença física, documentos oficiais
  - Emissão: semanas
  - Custo: alto (US$ 200-500/ano)
  - Navegador: nome da empresa em verde (obsoleto em Chrome/Firefox)
  - Ideal para: bancos, instituições financeiras

Implicação prática: DV é suficiente para criptografia segura. EV oferecia confiança visual, mas navegadores modernos removaram essa distinção. A segurança real está na criptografia, não no tipo de validação.

5. Ciclo de Vida e Renovação

Certificados têm prazo de validade por razões de segurança:

Por que expirar?
- Revogação implícita: certificados antigos deixam de ser válidos
- Limitação de danos: se chave privada vazar, expiração limita o impacto
- Atualização de algoritmos: novos padrões criptográficos

Práticas recomendadas:
- Let's Encrypt: 90 dias (renovação automática via ACME)
- CAs comerciais: 1-2 anos (renovação manual ou ACME)
- Monitoramento: scripts cron ou cert-manager (Kubernetes)

Exemplo de verificação de expiração com OpenSSL:

# Verificar validade de um certificado
openssl x509 -in certificado.pem -noout -dates

# Verificar se expirou
openssl x509 -in certificado.pem -noout -checkend 86400
# Retorna 0 se válido por mais 24h, 1 se expirando

# Script simples de monitoramento
#!/bin/bash
CERT="/etc/ssl/certs/meusite.pem"
if ! openssl x509 -in "$CERT" -noout -checkend 2592000; then
    echo "Certificado expira em menos de 30 dias!"
    # Disparar alerta (email, Slack, etc.)
fi

Consequências de expiração: o navegador exibe erro de TLS, o serviço fica indisponível, e usuários perdem confiança no site.

6. Revogação: Quando a Confiança é Quebrada

A revogação é necessária quando:

Motivos comuns:
- Chave privada comprometida (vazamento, roubo)
- Mudança de ownership do domínio
- Erro na emissão (CN incorreto, CA comprometida)
- Encerramento do serviço

Mecanismos de revogação:

CRL (Certificate Revocation List):
  - Lista de serial numbers revogados publicada pela CA
  - Cliente baixa periodicamente (latência, tamanho)
  - Problema: listas podem ter MBs, atualização lenta

OCSP (Online Certificate Status Protocol):
  - Consulta em tempo real: "Este certificado está revogado?"
  - Problema: cada requisição adiciona latência
  - Problema de privacidade: CA sabe quais sites você visita

OCSP Stapling:
  - Servidor obtém resposta OCSP assinada e a envia no handshake
  - Vantagem: sem latência extra para o cliente
  - Vantagem: privacidade preservada (CA não vê o cliente)

7. Boas Práticas para Devs

Geração segura de CSR e chave privada

# RSA 2048 bits (mínimo seguro)
openssl genrsa -out chave-privada.pem 2048
openssl req -new -key chave-privada.pem -out csr.pem \
    -subj "/CN=exemplo.com.br" \
    -addext "subjectAltName=DNS:exemplo.com.br,DNS:www.exemplo.com.br"

# ECDSA P-256 (mais rápido, mesma segurança)
openssl ecparam -genkey -name prime256v1 -out chave-privada.pem
openssl req -new -key chave-privada.pem -out csr.pem \
    -subj "/CN=exemplo.com.br" \
    -addext "subjectAltName=DNS:exemplo.com.br,DNS:www.exemplo.com.br"

# Proteção da chave privada
chmod 400 chave-privada.pem   # Apenas root pode ler

Cadeia completa no servidor

# Configuração incorreta: apenas o certificado do servidor
ssl_certificate /etc/ssl/certs/meusite.pem;
# ERRO: navegador não consegue validar a cadeia!

# Configuração correta: concatenação de leaf + intermediários
cat meusite.pem intermediario.pem > cadeia-completa.pem
ssl_certificate /etc/ssl/certs/cadeia-completa.pem;
ssl_certificate_key /etc/ssl/private/chave-privada.pem;

Testes de validação

# Testar conexão TLS
openssl s_client -connect exemplo.com.br:443 -showcerts

# Verificar cadeia completa
openssl s_client -connect exemplo.com.br:443 \
    -CAfile /etc/ssl/certs/ca-certificates.crt

# Verificar se OCSP Stapling está habilitado
openssl s_client -connect exemplo.com.br:443 -status
# Procure por "OCSP Response Status: successful"

# Teste online: SSL Labs (https://www.ssllabs.com/ssltest/)

Automação com Let's Encrypt e cert-manager

# Kubernetes: cert-manager com Let's Encrypt
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: meusite-tls
spec:
  secretName: meusite-tls-secret
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  commonName: exemplo.com.br
  dnsNames:
  - exemplo.com.br
  - www.exemplo.com.br

Referências