PEM, não JPG: Identificando uma Chave Privada Atrás de uma Extensão de Imagem
O desafio
Um arquivo chamado avatar.jpg foi encontrado na pasta de uploads de uma aplicação web, mas ele nunca aparece como foto. Abra-o no visualizador hexadecimal, leia os primeiros bytes como texto, compare-os com as assinaturas de referência e digite o tipo real do arquivo.
O que você vai aprender
- Ler os bytes iniciais como ASCII e reconhecer o cabeçalho PEM '-----BEGIN'
- Explicar que PEM é um invólucro de texto em base64 para chaves, certificados e CSRs
- Reconhecer o prefixo base64 'MIIE' como o início de uma chave codificada em DER
- Explicar por que um JPEG não pode começar com texto imprimível (ele começa com FF D8 FF)
- Distinguir PEM de JPEG, PNG e GZIP pelos seus primeiros bytes
Habilidades testadas
Pré-requisitos
- Familiaridade básica com chaves privadas e certificados
- Facilidade em converter bytes hexadecimais para seus caracteres ASCII
Como funciona
Nem toda assinatura é binária. PEM (Privacy-Enhanced Mail) é um formato de texto que envolve material criptográfico binário - chaves privadas, certificados, requisições de assinatura de certificado - em linhas base64 delimitadas por linhas de cabeçalho e rodapé legíveis por humanos. Todo bloco PEM começa com cinco traços, a palavra BEGIN, um rótulo, e mais cinco traços, por exemplo -----BEGIN PRIVATE KEY-----.
Neste arquivo, os bytes 2D 2D 2D 2D 2D são cinco hifens, 42 45 47 49 4E é BEGIN, e o restante forma PRIVATE KEY----- seguido de uma quebra de linha e uma linha base64 começando com MIIE. Esse prefixo MIIE é o indício característico do início de uma chave RSA/PKCS codificada em DER, uma vez convertida para base64. Então o arquivo inteiro é texto imprimível: uma chave privada envolvida em PEM.
Um JPEG de verdade começaria com FF D8 FF, bytes que não são texto imprimível de forma alguma, então o nome .jpg é um disfarce. A lista de referência contrasta a assinatura de traços do PEM com JPEG (FF D8 FF), PNG (89 50 4E 47) e GZIP (1F 8B). Apenas os traços correspondem. Uma chave privada dentro da pasta de uploads de uma aplicação web é uma exposição séria: qualquer pessoa que consiga lê-la pode se passar pelo servidor ou decifrar seu tráfego.
Erros comuns
- Confiar na extensão .jpg. O nome diz imagem, mas JPEGs começam com
FF D8 FF, não traços imprimíveis. - Ler apenas o hexadecimal e ignorar o ASCII. O caminho mais rápido é ler os bytes como texto, onde
-----BEGINsalta aos olhos. - Chamar de 'apenas um arquivo de texto'. É texto, mas o formato específico com o invólucro BEGIN/END é PEM, e ele contém uma chave privada.
- Confundir PEM com DER. DER é o binário bruto; PEM é o invólucro de texto em base64 e traços que você está vendo aqui.
Como se proteger
Chaves privadas nunca devem ficar em armazenamento acessível ao usuário, e uploads devem ser validados pelo tipo de conteúdo real.
- Faça varredura nos diretórios de upload e ativos em busca de cabeçalhos PEM (
-----BEGIN) e outros padrões de segredos, e alerte em qualquer correspondência. - Valide uploads pelos magic bytes em relação aos tipos permitidos, rejeitando tudo que não seja o formato de imagem esperado.
- Mantenha chaves privadas em um gerenciador de segredos ou repositório de chaves restrito, nunca em uma pasta servida pela web, e rotacione qualquer chave que tenha sido exposta.
- Sirva os uploads de usuários a partir de um domínio separado ou com um tipo de conteúdo forçado a download, para que uma chave vazada nunca seja executada ou interpretada no contexto da aplicação.