ssl keylog_filename: analise TLS no Wireshark

Publicado em: 02/10/2026
Tempo de leitura: 6 minutos
Tela de notebook com código para análise TLS usando ssl keylog_filename no Python

Depurar uma conexão HTTPS costuma ser difícil porque o TLS protege exatamente os dados que você gostaria de observar. O atributo SSLContext.keylog_filename do módulo ssl resolve parte desse problema ao permitir que o Python grave, em um arquivo local, os segredos de sessão usados durante o handshake. Ferramentas como o Wireshark podem ler esse arquivo e descriptografar o tráfego capturado, desde que você tenha autorização para analisar a conexão.

Esse recurso é especialmente útil em ambientes de desenvolvimento, testes de integração, análise de APIs internas, diagnóstico de incompatibilidades TLS e investigação de falhas de protocolo. Ele não desativa a criptografia na rede, não altera o certificado e não transforma HTTPS em HTTP. O tráfego continua criptografado; apenas o analista que possui o arquivo de chaves consegue interpretá-lo.

O que é keylog_filename

keylog_filename é uma propriedade de ssl.SSLContext. Ao receber um caminho de arquivo, o contexto passa a registrar segredos TLS no formato NSS Key Log. Esse formato é reconhecido por navegadores, bibliotecas e ferramentas de análise de pacotes. O arquivo normalmente contém linhas como CLIENT_RANDOM ou rótulos específicos do TLS 1.3, associando um identificador de sessão ao segredo correspondente.

O recurso depende de suporte da biblioteca OpenSSL usada pela instalação do Python. Em versões modernas, ele costuma funcionar em Linux, macOS e Windows, mas a disponibilidade real deve ser verificada no ambiente de execução.

Exemplo básico com urllib

import ssl
import urllib.request

contexto = ssl.create_default_context()
contexto.keylog_filename = "tls-keys.log"

with urllib.request.urlopen(
    "https://www.python.org/",
    context=contexto,
    timeout=10,
) as resposta:
    dados = resposta.read(200)
    print(resposta.status)
    print(dados[:80])

O código cria um contexto seguro com as autoridades certificadoras padrão e, em seguida, define o arquivo de log. Quando a conexão TLS é estabelecida, o Python acrescenta as chaves ao arquivo. Se você capturar o tráfego simultaneamente e configurar o Wireshark para usar tls-keys.log, poderá visualizar a camada HTTP dentro da sessão criptografada.

Como configurar o Wireshark

No Wireshark, abra as preferências do protocolo TLS e informe o caminho completo do arquivo no campo de log de chaves. Depois, inicie uma nova captura ou recarregue uma captura existente que corresponda às sessões registradas. O arquivo precisa conter os segredos das conexões específicas presentes no pacote; reutilizar um log antigo não ajuda em novas sessões.

Filtros como tls, http2 e http ajudam a localizar o fluxo. Em APIs modernas, é comum que o conteúdo apareça como HTTP/2, mesmo quando a URL começa com HTTPS. A documentação oficial do módulo ssl do Python explica o comportamento do contexto, enquanto a documentação do Wireshark sobre TLS detalha a importação do arquivo de chaves.

Uso com sockets

import socket
import ssl

contexto = ssl.create_default_context()
contexto.keylog_filename = "segredos-tls.log"

with socket.create_connection(("www.python.org", 443), timeout=10) as bruto:
    with contexto.wrap_socket(bruto, server_hostname="www.python.org") as seguro:
        seguro.sendall(
            b"GET / HTTP/1.1\r\nHost: www.python.org\r\nConnection: close\r\n\r\n"
        )
        resposta = seguro.recv(4096)
        print(resposta.decode("latin-1", errors="replace"))

Nesse exemplo, o arquivo é associado ao contexto antes do handshake. Esse detalhe é importante: configurar a propriedade depois que a sessão já foi negociada não recupera retroativamente os segredos.

Variável SSLKEYLOGFILE

Algumas aplicações e bibliotecas respeitam a variável de ambiente SSLKEYLOGFILE. O Python também pode usar essa variável ao criar contextos padrão em determinadas situações. Mesmo assim, definir context.keylog_filename explicitamente costuma ser melhor em testes, porque torna a intenção visível no código e evita depender do ambiente global.

export SSLKEYLOGFILE="$PWD/tls-keys.log"
python cliente.py

Em automações, prefira um diretório temporário e remova o arquivo ao final. O artigo sobre tempfile no Python ajuda a criar arquivos temporários com ciclo de vida controlado. Para entender melhor caminhos e diretórios, veja também pathlib no Python.

Segurança do arquivo de chaves

O arquivo gerado é extremamente sensível. Quem possui a captura de rede e o log correspondente pode descriptografar as sessões registradas. Por isso, nunca envie esse arquivo para repositórios Git, tickets públicos ou canais de suporte sem proteção. Adicione padrões como *.keylog e tls-keys.log ao .gitignore.

Também evite manter o recurso ativo em produção. Em servidores com alto volume, o arquivo cresce continuamente e concentra material criptográfico de muitas sessões. Isso cria risco de exposição, consumo de disco e problemas de concorrência. Restrinja permissões do arquivo ao usuário do processo e use um diretório protegido.

Função auxiliar segura

from pathlib import Path
import ssl


def criar_contexto_debug(caminho: Path, habilitado: bool = False) -> ssl.SSLContext:
    contexto = ssl.create_default_context()

    if habilitado:
        caminho.parent.mkdir(parents=True, exist_ok=True)
        contexto.keylog_filename = str(caminho)

    return contexto


contexto = criar_contexto_debug(
    Path(".debug") / "tls-keys.log",
    habilitado=True,
)

A flag explícita reduz o risco de ativar o recurso sem querer. Em projetos maiores, vincule essa opção a uma configuração local e bloqueie-a em ambientes de produção.

Integração com requests e httpx

A biblioteca requests não expõe diretamente um parâmetro de contexto SSL em sua função principal. É possível criar um adaptador HTTP personalizado para injetar um SSLContext. Já bibliotecas como httpx aceitam um contexto por meio do parâmetro verify.

import ssl
import httpx

contexto = ssl.create_default_context()
contexto.keylog_filename = "httpx-tls.log"

with httpx.Client(verify=contexto, timeout=10) as cliente:
    resposta = cliente.get("https://www.python.org/")
    print(resposta.status_code)

Ao investigar clientes HTTP, vale revisar o artigo sobre urllib.request no Python e o guia de requisições HTTP com Python. Esses conteúdos ajudam a separar erros de aplicação, DNS, TCP, certificado e protocolo.

Erros comuns

Um erro frequente é usar um caminho sem permissão de escrita. Nesse caso, a criação do arquivo pode falhar ou o log permanecer vazio. Outro problema é capturar uma interface de rede diferente daquela usada pela aplicação. Em contêineres, VPNs e WSL, a interface correta pode não ser a mais óbvia.

Também é comum esperar que o log descriptografe sessões antigas. As chaves só são registradas para handshakes realizados enquanto o contexto está configurado. Reuso de conexão, cache e pooling podem fazer com que nenhuma nova linha apareça. Feche o cliente, force uma nova sessão e repita a captura.

TLS 1.3 e HTTP/2

O TLS 1.3 usa vários segredos durante o handshake e a comunicação. O formato NSS Key Log registra rótulos adequados, e versões recentes do Wireshark conseguem interpretar esses dados. Para HTTP/2, a descriptografia TLS é apenas a primeira etapa; depois disso, o Wireshark precisa decodificar os frames do protocolo.

Quando usar

Use keylog_filename quando precisar confirmar cabeçalhos, negociação ALPN, redirecionamentos, cookies, compactação, frames HTTP/2 ou comportamento de uma API sob TLS. Ele também ajuda a comparar o que a aplicação pensa que enviou com o que realmente saiu pela rede.

Não use o recurso para interceptar tráfego de terceiros, contornar controles ou coletar credenciais. A análise deve ocorrer em sistemas, contas e ambientes para os quais você possui autorização explícita.

Checklist de depuração

  • Crie um contexto com validação de certificado ativa.
  • Defina o arquivo antes do handshake.
  • Proteja o log com permissões restritas.
  • Capture a interface correta.
  • Configure o caminho completo no Wireshark.
  • Force uma nova conexão quando necessário.
  • Remova o arquivo após a investigação.

Conclusão

SSLContext.keylog_filename oferece uma forma prática de observar conexões TLS criadas pelo Python sem desativar a criptografia. Com um contexto dedicado, um arquivo protegido e uma captura autorizada, você consegue diagnosticar problemas de HTTPS, HTTP/2 e APIs com muito mais precisão. O principal cuidado é tratar o arquivo de chaves como segredo temporário e nunca deixá-lo ativo em produção sem uma justificativa forte.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Notebook com código e banco SQLite para sqlite3 autocommit no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    sqlite3 autocommit: controle transações no Python

    Aprenda sqlite3 autocommit no Python para controlar transações, commits, rollbacks, compatibilidade e bloqueios com segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    02/10/2026
    Programador trabalhando com objetos imutáveis e copy.replace no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    copy.replace: atualize objetos imutáveis no Python

    Aprenda copy.replace no Python para criar novas versões de objetos com alterações pontuais, imutabilidade e validação segura.

    Ler mais

    Tempo de leitura: 6 minutos
    01/10/2026
    Estrutura de arquivos e código para pathlib.Path.info no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pathlib.Path.info: cache de metadados de arquivos

    Aprenda pathlib.Path.info no Python para consultar tipos de arquivos com cache, iterar diretórios e evitar chamadas desnecessárias ao sistema.

    Ler mais

    Tempo de leitura: 7 minutos
    01/10/2026
    Notebook com material de testes em Python para loop_factory e asyncio
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    loop_factory: isole event loops em testes asyncio

    Aprenda loop_factory em IsolatedAsyncioTestCase para criar testes asyncio isolados, previsíveis e sem tarefas pendentes.

    Ler mais

    Tempo de leitura: 5 minutos
    30/09/2026
    Desenvolvedora navegando em arquivos ZIP com zipfile.Path no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    zipfile.Path: navegue em ZIPs sem extrair arquivos

    Aprenda zipfile.Path no Python para navegar, ler e validar arquivos dentro de ZIPs sem extrair tudo.

    Ler mais

    Tempo de leitura: 5 minutos
    30/09/2026
    Programador trabalhando com cabeçalhos de e-mail no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    email.headerregistry: cabeçalhos de e-mail seguros

    Aprenda email.headerregistry no Python para criar e analisar cabeçalhos, endereços, grupos, datas e parâmetros com segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    29/09/2026