Aula 19 - Segurança na Camada de Transporte (TLS/SSL Handshake) 🔐
Objetivo Pedagógico
Objetivo: Examinar a engenharia de segurança do protocolo TLS 1.3: troca de chaves Diffie-Hellman efêmero (ECDHE), cifras autenticadas (AEAD), validação de cadeias X.509 e prevenção de ataques Man-in-the-Middle (MitM).
📑 1. Fundamentos Teóricos & Análise Técnica
O protocolo Transport Layer Security (TLS) é a pedra angular da confidencialidade, autenticidade e integridade nas comunicações da Internet moderna.
Com a consolidação do TLS 1.3 (RFC 8446), o protocolo passou por uma profunda refatoração arquitetural para eliminar vulnerabilidades herdadas do TLS 1.2: 1. Redução de Latência do Handshake: O TLS 1.2 exigia 2 RTTs para concluir o aperto de mão com troca de parâmetros de cifra. No TLS 1.3, o handshake foi reduzido para 1 RTT padrão e 0-RTT para reconexões. 2. Eliminação de Cifras Inseguras: Foram removidos algoritmos obsoletos e vulneráveis como RC4, DES, 3DES, MD5, SHA-1, além do modo de operação CBC e da troca de chaves estática baseada em RSA puro (que não oferecia sigilo de encaminhamento). 3. Perfect Forward Secrecy (PFS) Obrigatório: O TLS 1.3 exige exclusivamente esquemas efêmeros baseados em curvas elípticas (ECDHE - Elliptic Curve Diffie-Hellman Ephemeral). Caso a chave privada do servidor seja comprometida no futuro, sessões pretéritas gravadas por adversários permanecem indecifráveis. 4. Cifras AEAD (Authenticated Encryption with Associated Data): As únicas suites de cifras permitidas combinam criptografia e código de autenticação de mensagem em uma operação atômica (ex: AES-256-GCM, CHACHA20-POLY1305), inviabilizando ataques de padding oracle.
📐 Arquitetura Conceitual & Diagrama de Fluxo
sequenceDiagram
autonumber
participant Client as Cliente (Browser / Agente)
participant Server as Servidor Seguro (TLS 1.3)
Note over Client,Server: TLS 1.3 Handshake em 1 RTT
Client->>Server: ClientHello [Versões suportadas, Key Share ECDHE (Curve25519), Cifras AEAD]
Server->>Client: ServerHello [Key Share ECDHE aceito] + {EncryptedExtensions, Certificado X.509, CertificateVerify, Finished}
Note over Client: Cliente valida assinatura X.509 na cadeia AC e calcula a chave mestre secreta
Client->>Server: {Finished}
Note over Client,Server: Canal Criptografado Ativo com Chaves de Aplicação Simétricas!
Client->>Server: Requisição HTTP Segura (Cifrada com AES-256-GCM) 🔍 Pilares e Diretrizes Técnicas
Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Infraestrutura de Chaves Públicas (PKI): Verificação da cadeia de confiança de certificados assinados por Autoridades Certificadoras (CAs) confiáveis via OCSP e CRLs. - Diffie-Hellman Efêmero (ECDHE): Cálculo de chave simétrica temporária compartilhada sobre curvas elípticas sem tráfego da chave pela rede. - Server Name Indication (SNI / ECH): Mecanismo que envia o hostname de destino no handshake; Encrypted Client Hello (ECH) cifra até mesmo o SNI para garantir privacidade contra espionagem de DNS/ISP. - Application-Layer Protocol Negotiation (ALPN): Negociação do protocolo de camada superior (h2, h3, http/1.1) diretamente dentro da extensão TLS.
🛠️ 2. Implementação Prática em TLS 1.3, Criptografia de Chave Pública e PKI
Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:
// tls_inspector.py (Inspeção de Certificado X.509 e Parâmetros Criptográficos TLS)
import ssl
import socket
from datetime import datetime
def inspect_tls_connection(hostname: str, port: int = 443):
"""Conecta e extrai metadados criptográficos da sessão TLS."""
context = ssl.create_default_context()
# Exige estritamente TLS 1.3 para conexões modernas seguras
context.minimum_version = ssl.TLSVersion.TLSv1_3
with socket.create_connection((hostname, port), timeout=5) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
cert = ssock.getpeercert()
cipher, proto, bits = ssock.cipher()
print(f"=== Inspeção de Sessão TLS para {hostname} ===")
print(f"Protocolo Negociado : {proto}")
print(f"Cifra Utilizada : {cipher} ({bits} bits)")
print(f"Sujeito Certificado : {dict(x[0] for x in cert.get('subject', []))}")
print(f"Emissor (CA) : {dict(x[0] for x in cert.get('issuer', []))}")
exp_date = datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z')
print(f"Validade Até : {exp_date.strftime('%Y-%m-%d %H:%M:%S UTC')}")
if __name__ == '__main__':
inspect_tls_connection("github.com")
💡 Análise Passo a Passo do Código
- Exigência de TLSv1_3: Impede tentativas de downgrade attack por intermediários maliciosos.
- Validação Estrita de SNI: Dispara
server_hostnamepara evitar que o servidor sirva certificado genérico incorreto. - Inspeção de Cifras AEAD: Confirma a utilização de canais protegidos com garantia de integridade matemática.
🎯 3. Próximos Passos & Sequência Didática
-
Slides da Aula
-
Quiz de Fixação
-
Exercícios Práticos
-
Desafio de Projeto