Introdução
Quando eu falo de certificados SSL/TLS em times de backend, quase sempre encontro o mesmo atalho perigoso: “não conecta no ambiente de teste, então coloca verify=False no Python ou callback => true no .NET e segue”. Esse atalho parece inofensivo porque resolve o erro de conexão na hora, mas ele remove justamente o mecanismo que impede ataques de man-in-the-middle (MITM). Em outras palavras: a aplicação continua “funcionando”, mas deixa de saber se está falando com o servidor legítimo.
Neste artigo, eu vou explicar como certificados SSL/TLS funcionam de forma prática e, principalmente, como eu valido certificado corretamente em aplicações .NET e Python em cenários reais de produção. Vou cobrir handshake TLS 1.3, cadeia de confiança X.509, trust store, mTLS, containers e o cenário que mais gera dúvida em times de backend: uma API chamando outra API por HTTPS com Load Balancer, NGINX, HAProxy, F5, Azure Application Gateway, AWS ALB ou Kubernetes Ingress no meio. A ideia é sair da teoria abstrata e ir para código e arquitetura que você pode colocar em produção sem vergonha de auditoria.
Quando uma API chama https://api2.interno.empresa.com, ela valida o certificado apresentado pelo endpoint HTTPS que recebeu a conexão. Em muitas arquiteturas, esse endpoint não é o container da API 2; é um Load Balancer ou Proxy Reverso que faz TLS Termination. Depois disso, o tráfego pode seguir para o backend por HTTP interno, HTTPS interno com nova validação, ou TLS passthrough até o próprio container. Entender onde o TLS termina evita uma confusão clássica: achar que a API cliente sempre valida o certificado do container.
Este é o quarto artigo da série Segurança para Devs. Nos artigos anteriores eu tratei de autenticação, BFF e API Gateway. Agora eu foco na camada de transporte, porque sem um TLS validado corretamente todo o resto fica frágil: JWT forte não salva um canal comprometido, OAuth2 correto não protege contra interceptação de tráfego e mTLS mal configurado pode virar teatro de segurança.
ℹ️ Informação: TLS 1.3 (RFC 8446) reduziu o handshake para 1-RTT no caso comum e removeu suites e algoritmos antigos inseguros. Isso melhora segurança e latência ao mesmo tempo.
Se você quer um resumo da tese logo no início: validar certificado não é opcional. É controle de integridade do canal. Quando eu desativo verificação para “fazer funcionar”, eu troco um erro explícito por um risco silencioso. O objetivo daqui é te mostrar como manter conexão segura sem cair nesses atalhos.
Pré-requisitos
Para acompanhar os exemplos sem fricção, eu recomendo este ambiente:
- .NET 10 SDK instalado para compilar os samples C#.
- Python 3.12+ com
requestsdisponível. - Conhecimento básico de HTTP/HTTPS, status codes e cabeçalhos.
- Familiaridade mínima com Docker e imagens Linux (Debian/Ubuntu) para a parte de container.
Também ajuda ter acesso a um endpoint HTTPS de teste com certificado próprio (CA interna) e, se quiser reproduzir mTLS, um certificado de cliente (.pfx no .NET ou par .crt/.key no Python).
O que é TLS/SSL e por que “SSL” é termo legado
No uso diário, eu ainda ouço “certificado SSL” o tempo todo, inclusive em documentação de produtos. Tecnicamente, porém, SSL (Secure Sockets Layer) é o nome histórico. SSL 2.0 e SSL 3.0 estão obsoletos há anos por problemas graves de segurança. O protocolo atual é TLS (Transport Layer Security), com foco moderno em TLS 1.2 e TLS 1.3.
Por que essa distinção importa? Porque linguagem molda decisão técnica. Quando eu trato TLS como “SSL”, eu costumo herdar mentalidade antiga: compatibilidade acima de segurança, cifra fraca para atender cliente legado, tolerância a certificados mal emitidos. Quando eu trato como TLS moderno, eu priorizo suites seguras, validação estrita e observabilidade de expiração/revogação.
Na prática, o certificado digital é um documento X.509 que vincula uma identidade (domínio, organização, serviço) a uma chave pública. O TLS usa esse certificado para estabelecer um canal criptografado e autenticado entre cliente e servidor. O cliente valida se o certificado é confiável, se o nome do host bate com SAN/CN e se a cadeia até uma CA raiz confiável fecha corretamente.
Eu gosto de resumir assim:
- Criptografia protege confidencialidade do tráfego.
- Integridade garante que o pacote não foi alterado.
- Autenticidade confirma com quem eu estou falando.
Sem validação de certificado, eu mantenho criptografia, mas perco autenticidade. É exatamente esse o ponto que um atacante MITM explora.
⚠️ Atenção: Se o cliente aceita qualquer certificado, o TLS vira túnel criptografado para o atacante certo. Criptografado, porém comprometido.
Como funciona o handshake TLS 1.3
O handshake TLS 1.3 é o processo de negociação entre cliente e servidor antes dos dados de aplicação trafegarem. Eu acho útil enxergar esse fluxo em cinco blocos:
- ClientHello: o cliente envia versões de TLS suportadas, suites criptográficas, extensões (como SNI e ALPN) e chave efêmera para ECDHE.
- ServerHello: o servidor escolhe versão/suite, responde com sua chave efêmera e inicia parâmetros da sessão.
- Certificate + CertificateVerify: o servidor envia cadeia de certificados e prova posse da chave privada.
- Finished: ambos confirmam que chegaram às mesmas chaves de sessão.
- Application Data: tráfego HTTP passa a ser protegido pelo canal estabelecido.

A mudança mais importante em relação a versões antigas é a redução de complexidade. TLS 1.3 removeu renegociação insegura, removeu RSA key exchange e tornou ECDHE o padrão para perfect forward secrecy (PFS). Em termos práticos, mesmo que a chave privada do servidor vaze no futuro, sessões antigas não são descriptografadas retroativamente.
Outro ponto que eu observo em produção: erro de handshake costuma apontar mais para configuração de certificado/trust store do que para bug de código. Por isso, log detalhado de falha TLS é essencial. Quando eu capturo hostname, issuer, thumbprint e status da cadeia, eu resolvo incidente muito mais rápido.
ℹ️ Informação: TLS 1.3 usa apenas suites AEAD modernas (como AES-GCM e ChaCha20-Poly1305), reduzindo superfície de ataque e simplificando hardening operacional.
Cadeia de confiança: CA raiz, intermediária e certificado de entidade final
Certificado não é uma entidade isolada. Ele participa de uma cadeia de confiança. Em geral, eu tenho:
- Certificado de entidade final: pertence ao servidor (por exemplo
api.minhaempresa.com). - CA intermediária: emite certificados de servidor e reduz exposição da raiz.
- CA raiz: âncora de confiança presente no trust store do sistema cliente.
Quando o cliente recebe o certificado do servidor, ele tenta montar essa cadeia até uma raiz confiável localmente. Se a raiz não estiver no trust store, a validação falha com erro de untrusted root. Isso é comum em ambientes corporativos com PKI interna, laboratórios e ambientes air-gapped.
Em certificados públicos de internet, a cadeia normalmente termina em uma CA raiz já presente no trust store do sistema ou navegador. É o caso de certificados emitidos por ACs públicas (autoridades certificadoras) como Certisign, DigiCert, GlobalSign e Let’s Encrypt. Nesses cenários, eu não preciso distribuir CA interna para clientes externos; o foco passa a ser enviar a cadeia intermediária correta no servidor e manter renovação em dia.
No dia a dia, os problemas mais frequentes que eu vejo são:
- Servidor sem enviar intermediária correta.
- Certificado expirado ou fora da janela de validade.
- SAN sem hostname esperado.
- Cadeia confiável no host, mas não no container.
Esse último é traiçoeiro: no meu notebook funciona, no pod não. O motivo normalmente é simples: a imagem não recebeu a CA interna no trust store do sistema.
Quando eu trabalho com CA privada, minha abordagem é dupla:
- Instalo a CA no trust store do sistema no ambiente controlado.
- Quando necessário, uso trust customizado na aplicação para cenários isolados.
Essa segunda opção precisa de disciplina. Trust customizado é ferramenta boa quando bem delimitada, mas perigosa se virar regra geral sem governança.
Validando certificados corretamente em .NET
No .NET, minha referência para cliente HTTP moderno é HttpClient com SocketsHttpHandler. Ele permite configurar TLS sem truques inseguros. O ponto chave é: eu nunca retorno true de forma incondicional no callback.
Quando o endpoint usa certificado público emitido por AC pública confiável, o caminho padrão do .NET já resolve a validação usando o trust store do sistema. Eu só adiciono trust customizado quando tenho CA privada ou requisito de isolamento específico.
Trecho de sample com trust customizado e validação real da cadeia:
| |
📂 Código Fonte: O exemplo completo está disponível no repositório de exemplos do blog:
BlogSamples/Security/Certificates/
No validator, eu recuso imediatamente RemoteCertificateNotAvailable e RemoteCertificateNameMismatch, depois reconstruo a cadeia com política estrita (NoFlag) e revogação online. Se houver CA personalizada, aplico TrustMode = CustomRootTrust e adiciono a raiz no CustomTrustStore.
Exemplo de criação de cliente mTLS:
| |
📂 Código Fonte: O exemplo completo está disponível no repositório de exemplos do blog:
BlogSamples/Security/Certificates/
Dois detalhes operacionais fazem diferença em produção:
- Eu prefiro
X509CertificateLoaderem vez de construtores legados para evitar warnings e garantir compatibilidade atual. - Eu monitoro erros de cadeia e expiração em logs estruturados para acionar alerta antes da queda.
Validando certificados corretamente em Python
No Python, eu vejo o mesmo anti-pattern do .NET: verify=False para “destravar” integração. Em produção, isso não pode existir. O caminho correto com requests é informar o bundle de CA confiável em verify, ou manter o trust store padrão quando usa CA pública.
Exemplo seguro com requests:
| |
Se eu preciso de controle mais fino, crio SSLContext explícito:
| |
📂 Código Fonte: O exemplo completo está disponível no repositório de exemplos do blog:
BlogSamples/python/
Para mTLS no requests, eu passo par certificado/chave do cliente no parâmetro cert:
| |
Essa abordagem me atende bem para automações, workers e integrações backend-to-backend. Em APIs sensíveis, eu combino mTLS com token de aplicação para defesa em camadas.
Para certificado público de servidor (por exemplo, domínio público com emissão por Certisign ou outra AC pública), o padrão costuma ser manter verify=True e usar o trust store nativo, sem CA bundle customizado. Eu só uso verify apontando arquivo quando preciso confiar em CA privada ou cadeia fora do padrão do sistema.
mTLS: quando o cliente também apresenta certificado
No TLS tradicional, só o servidor apresenta certificado. No mTLS (mutual TLS), cliente e servidor apresentam certificado. Eu uso isso quando quero identidade forte de serviço para serviço sem depender apenas de segredo estático.
Cenários comuns onde mTLS vale o custo:
- Comunicação interna entre API Gateway e serviços críticos.
- Integração B2B com parceiros fixos e requisitos de compliance.
- Ambientes financeiros e industriais onde identidade criptográfica é obrigatória.
mTLS não substitui autorização de negócio. Ele prova identidade técnica do cliente, mas ainda preciso decidir se aquele cliente pode executar aquela ação. Na prática, eu trato mTLS como controle de borda e mantenho autorização por escopo/claims na aplicação.
Se você quiser contexto arquitetural da série, este artigo conversa diretamente com API Gateway: A Peça que Falta na Segurança da Sua SPA, onde eu mostro como gateway aplica políticas em escala.
Certificados em containers
Container muda bastante o jogo porque o trust store do host não é herdado automaticamente da forma que muita gente imagina. Cada imagem tem seu próprio conjunto de CAs. Quando eu recebo erro de TLS só no pod, quase sempre é CA ausente no filesystem da imagem.
No Debian/Ubuntu, o fluxo padrão é:
| |
Com isso, bibliotecas que usam trust store do sistema passam a confiar na CA interna. Eu evito colocar certificado sensível em variável de ambiente. Para certificado de cliente e chave privada, eu monto secret em tmpfs (como /run/secrets) e limito permissão de leitura ao processo da aplicação.
Também tomo cuidado com rotação:
- CA e certs com data de vencimento monitorada.
- Pipeline de imagem preparado para troca sem downtime desnecessário.
- Health checks que falham cedo quando cadeia não valida.
Em Kubernetes, isso normalmente significa combinar Secret/CSI driver com rollout controlado e observabilidade de handshake.
TLS Termination em Load Balancers e Reverse Proxies
Em arquitetura corporativa, a chamada raramente é tão direta quanto “API 1 abre TLS com o container da API 2”. O desenho mais comum é este:
| |
Nesse modelo, a API 1 valida o certificado do Load Balancer ou Proxy Reverso, porque é ele que aparece como servidor TLS na conexão. Se o DNS api2.interno.empresa.com aponta para um NGINX, F5, HAProxy, Azure Application Gateway, AWS ALB ou Ingress Controller, é esse componente que apresenta o certificado para o cliente. O container da API 2 pode estar servindo HTTP puro em uma rede privada e, ainda assim, a chamada externa da API 1 continua sendo HTTPS.
O código da API cliente não precisa mudar por causa disso:
| |
Do ponto de vista do HttpClient, o fluxo é simples: resolver DNS, conectar no IP retornado, receber o certificado do servidor TLS, validar hostname/cadeia/validade e só então enviar HTTP dentro do túnel criptografado. O que acontece depois do Load Balancer é transparente para a API cliente.
ℹ️ Informação: Se a API cliente chama
https://api2.interno.empresa.com, esse nome precisa estar no SAN do certificado apresentado pelo Load Balancer ou Proxy Reverso. O SAN do certificado do container só importa para quem abre TLS diretamente com o container.
A pergunta que costuma aparecer é: “se o certificado está no Load Balancer, por que a API precisa validá-lo?” A resposta é que, para a API cliente, o Load Balancer é o servidor TLS. A validação impede que a API envie dados para um endpoint que apenas parece ser api2.interno.empresa.com, mas não tem um certificado confiável para esse nome. TLS não autentica “o container” por definição; TLS autentica a outra ponta da conexão que foi aberta.
Quando o proxy reverso tem uma CA
A frase “o proxy reverso tem o certificado CA” pode significar três coisas diferentes, e cada uma cobre um cenário distinto:
| O que o proxy possui | Para que serve | Cenário coberto |
|---|---|---|
| Certificado de servidor assinado por uma CA | Apresentar identidade HTTPS aos clientes | TLS Termination no Load Balancer/Proxy |
| Certificado da CA confiável | Validar o certificado de um upstream HTTPS | TLS Re-encryption entre proxy e backend |
| CA de clientes confiáveis | Validar certificados apresentados por clientes | mTLS na borda do proxy reverso |
No primeiro caso, o proxy não “tem a CA” como chave de autoridade; ele tem um certificado de servidor emitido por uma CA pública ou privada. Esse é o caso mais comum de TLS Termination: API 1 valida o certificado do proxy, e o proxy encaminha para a API 2.
No segundo caso, o proxy tem o certificado público da CA no trust store dele para validar o backend. Aqui o proxy atua como cliente TLS quando chama https://api2-backend.interno.local. A API 1 valida o proxy; o proxy valida o backend. São duas sessões TLS independentes.
No terceiro caso, o proxy tem uma CA de clientes confiáveis para exigir mTLS na entrada. A API 1 apresenta um certificado de cliente, o proxy valida esse certificado contra a CA configurada e só então aceita a conexão. Isso autentica a API chamadora na borda, mas não substitui autorização de negócio dentro da aplicação.
⚠️ Atenção: A chave privada de uma CA não deve ficar em Load Balancer, NGINX ou container de aplicação. O proxy precisa do certificado de servidor e, quando necessário, do certificado público da CA para validação. A chave privada da CA pertence ao processo de emissão, não ao runtime da API.
TLS Termination, Re-encryption e Passthrough
Os três modelos abaixo resolvem problemas diferentes. Eu gosto de escolher explicitamente um deles em desenho de arquitetura, porque a frase “usa HTTPS” sozinha não diz onde o TLS começa, termina ou é reaberto.
| Modelo | Fluxo | Quem apresenta certificado ao cliente? | Backend usa TLS? | Quando usar |
|---|---|---|---|---|
| TLS Termination | Cliente -> HTTPS -> LB/proxy -> HTTP -> API | LB/proxy | Não | Rede privada controlada, menor complexidade operacional |
| TLS Re-encryption | Cliente -> HTTPS -> LB/proxy -> HTTPS -> API | LB/proxy | Sim | Ambientes regulados, rede interna compartilhada ou tráfego sensível |
| TLS Passthrough | Cliente -> HTTPS -> LB TCP -> API | API/backend | Sim | Quando o LB não deve encerrar TLS nem inspecionar HTTP |
Em TLS Termination, o Load Balancer encerra a sessão TLS e passa a enxergar a requisição HTTP. Isso permite roteamento por path, headers, cookies e políticas de WAF, mas exige confiança na rede entre proxy e backend. Em muitos ambientes internos, esse desenho é aceitável quando existe segmentação de rede, firewall, autenticação entre serviços e observabilidade.
Em TLS Re-encryption, o proxy encerra o TLS do cliente e abre uma nova conexão HTTPS para o backend. Esse desenho cria duas proteções independentes: cliente valida proxy, e proxy valida backend. É o modelo que eu prefiro quando o tráfego passa por rede compartilhada, Kubernetes multi-tenant, service mesh ou ambiente com requisito regulatório mais forte.
Em TLS Passthrough, o Load Balancer opera em camada TCP e encaminha a conexão TLS sem abrir o conteúdo HTTP. O certificado apresentado ao cliente é o certificado do backend, não do proxy. O ganho é manter TLS ponta a ponta até a aplicação; a perda é reduzir recursos de roteamento HTTP, inspeção e WAF na borda.
NGINX como ponto de terminação TLS
Quando eu uso NGINX como web server/reverse proxy, o ponto central é sempre o mesmo: o certificado apresentado ao cliente fica no bloco server HTTPS, via ssl_certificate e ssl_certificate_key.
Certificado público apresentado ao cliente
No cenário público (AC pública como Certisign, DigiCert, GlobalSign ou Let’s Encrypt), minha prática é configurar o NGINX com cadeia completa (fullchain) para evitar erro de cadeia incompleta no cliente:
| |
Nesse exemplo, o NGINX faz TLS Termination. O cliente valida api.minhaempresa.com, recebe o certificado do NGINX e só depois a requisição segue para http://app:8080 dentro da rede interna.
mTLS entre cliente e NGINX
No cenário interno com CA privada, a configuração do certificado no NGINX é parecida, mas os clientes só vão confiar se a CA interna estiver no trust store deles. Se o endpoint exigir mTLS de cliente, eu habilito verificação explícita:
| |
Aqui o NGINX usa ssl_client_certificate como lista de CAs confiáveis para validar certificados apresentados por clientes. Isso cobre o cenário em que a API 1 também precisa provar identidade por certificado antes de acessar a API 2.
NGINX validando certificado do upstream HTTPS
Quando o NGINX também atua como cliente TLS para um upstream HTTPS interno, eu ativo validação de certificado no proxy para não cair no anti-pattern de confiar cegamente:
| |
Com isso, eu cubro os dois lados da segurança: o certificado que o NGINX apresenta para fora e a validação do certificado quando ele chama serviços HTTPS internos.
Exemplo Prático
Como exemplo prático, eu uso duas implementações de cliente e três topologias de infraestrutura para validar:
- .NET em
src/BlogSamples/Security/Certificates/comHttpClientseguro, trust customizado e mTLS. - Python em
python/ssl_validation_example.pycomrequestseSSLContextestrito. - API chamando API por Load Balancer: a API 1 acessa
https://api2.interno.empresa.come valida o certificado apresentado pelo Load Balancer ou Reverse Proxy. - TLS Re-encryption: o proxy encerra HTTPS na borda e abre uma nova conexão HTTPS validada até a API backend.
- TLS Passthrough: o proxy não encerra TLS; o certificado visto pelo cliente é o certificado do backend.
Fluxo que eu recomendo para validar ponta a ponta:
- Suba um endpoint HTTPS de teste com CA privada.
- Aponte um DNS interno para o Load Balancer ou NGINX.
- Execute cliente .NET com
CriarClienteComCaPrivadachamando o DNS público do serviço, não o nome do container. - Execute script Python passando
TLS_CA_BUNDLE,TLS_CLIENT_CERTeTLS_CLIENT_KEYquando houver mTLS. - Verifique logs de cadeia e hostname em ambos.
- Force erro (hostname errado ou cert expirado) para confirmar que a aplicação falha de forma segura.
📝 Exemplo: Se o endpoint for
https://api.interna.locale o certificado tiver SAN apenas paraapi.dev.local, a conexão deve falhar por mismatch de nome. Esse é o comportamento correto e esperado.
Com esse fluxo, eu provo duas coisas para o time: que o caminho feliz funciona e que o caminho de falha falha do jeito certo. Segurança madura não é apenas “funciona quando tudo está bonito”; é previsível quando algo sai do esperado.
Dicas e Boas Práticas
Nunca desabilite validação (
verify=False,CERT_NONE, callback=> true). Quando eu removo validação, eu elimino autenticidade do canal e abro caminho para MITM. Em vez disso, eu corrijo trust store, SAN ou cadeia.Prefira pin de CA/intermediária ao invés de pin de certificado de entidade final. Pin no leaf quebra com renovação frequente. Pin em CA bem governada reduz manutenção sem perder controle.
Monitore expiração e falhas de handshake como métrica de plataforma. Eu trato erro TLS como sinal operacional de alto valor. Alertar 30 dias antes da expiração evita incidente evitável.
Use mTLS em tráfego lateral sensível, especialmente entre gateway e backend. Isso reduz risco de chamada direta indevida a serviços internos. Ainda assim, mantenha autorização por claims/escopos no app.
Padronize instalação de CAs em imagens e ambientes locais. Eu documento o passo de trust store por distro e automatizo no Dockerfile. Isso elimina “na minha máquina funciona” de TLS.
Em domínio público, prefira AC pública bem suportada e automação de renovação. Isso reduz fricção de distribuição de confiança para clientes externos. Mesmo com AC pública, eu valido cadeia enviada pelo servidor e monitoro expiração para evitar indisponibilidade.
Garanta que o SAN corresponda ao DNS usado pelo cliente. Se a API chama
api2.interno.empresa.com, esse nome precisa estar no certificado apresentado pelo Load Balancer ou Proxy Reverso. O certificado do backend só entra na validação quando existe TLS Re-encryption ou Passthrough.Escolha explicitamente entre Termination, Re-encryption e Passthrough. TLS Termination simplifica operação, Re-encryption protege também o trecho interno, e Passthrough mantém o certificado no backend. Não trate todos como “HTTPS” genérico, porque cada modelo muda quem valida quem.
Não coloque chave privada de CA no proxy reverso. O proxy precisa da chave privada do certificado de servidor para apresentar sua identidade e dos certificados públicos das CAs que usa para validar clientes ou upstreams. A chave privada da CA deve ficar protegida no processo de emissão, fora do runtime.
Teste cenários negativos de forma intencional. Inclua casos com hostname inválido, cert expirado e cadeia incompleta no pipeline de qualidade. Se o cliente aceitar esses cenários, algo está errado.
Resumo Objetivo
- TLS 1.3 — é o protocolo moderno de transporte seguro; SSL é legado obsoleto e não deve ser alvo de configuração nova.
- Validação de certificado — precisa confirmar cadeia de confiança, hostname (SAN/CN), validade temporal e, quando aplicável, revogação.
- TLS Termination — ocorre quando Load Balancer ou Reverse Proxy encerra HTTPS, apresenta o certificado ao cliente e encaminha a requisição ao backend por HTTP ou HTTPS.
- TLS Re-encryption — cria duas sessões TLS independentes: cliente-proxy e proxy-backend; o cliente valida o proxy, e o proxy valida a API backend.
- TLS Passthrough — mantém a sessão TLS até o backend; o certificado visto pelo cliente é o da aplicação, mas o proxy perde inspeção HTTP detalhada.
- Clientes .NET e Python — devem validar certificados com
SocketsHttpHandler,CustomRootTrust,verify,CERT_REQUIREDecheck_hostname=True, sem bypass inseguro. - mTLS — adiciona autenticação do cliente por certificado e é especialmente útil em comunicação service-to-service crítica.
- NGINX com HTTPS — usa
ssl_certificateessl_certificate_keypara apresentar identidade;ssl_client_certificatevalida clientes mTLS eproxy_ssl_trusted_certificatevalida upstreams.
Leia Também
- Autenticação e Autorização: JWT, OAuth2 e OpenID Connect
- BFF Backend For Frontend: Segurança em SPAs
- API Gateway: A Peça que Falta na Segurança da Sua SPA
- Prevenção de DDoS: Infraestrutura e Segurança em Aplicações Modernas
Referências
- RFC 8446 - The Transport Layer Security (TLS) Protocol Version 1.3 — especificação oficial do TLS 1.3.
- RFC 5280 - Internet X.509 Public Key Infrastructure Certificate and CRL Profile — perfil de certificados X.509 e validação de cadeia.
- Microsoft Docs - X509Chain — API de construção e validação de cadeia no .NET.
- Microsoft Docs - SocketsHttpHandler — configuração de cliente HTTP moderno no .NET.
- Python Docs - ssl — configuração de contexto TLS no Python.
- Requests Docs - SSL Cert Verification — verificação de certificado na biblioteca requests.
- OWASP Transport Layer Security Cheat Sheet — guia prático de hardening TLS.
- NGINX Docs - ngx_http_ssl_module — diretivas
ssl_certificate,ssl_certificate_keye configuração HTTPS no blocoserver. - NGINX Docs - ngx_http_proxy_module — diretivas
proxy_ssl_verifyeproxy_ssl_trusted_certificatepara validação TLS de upstream. - HAProxy Documentation - SSL/TLS — configuração de terminação TLS, certificados e validação em HAProxy.
- Kubernetes Documentation - Ingress TLS — uso de TLS em Ingress Controllers no Kubernetes.
- Azure Application Gateway - SSL termination and end-to-end SSL — opções de terminação TLS e criptografia ponta a ponta no Application Gateway.
- AWS Elastic Load Balancing - HTTPS listeners — configuração de listeners HTTPS e certificados em Application Load Balancer.

Ao comentar, você concorda com nossa Política de Privacidade, Termos de Uso e Política de Exclusão de Dados.