PEM vs DER não é uma escolha entre dados diferentes: um certificado, uma chave, um CSR ou uma CRL são sempre definidos como ASN.1 codificado em DER, e o PEM é um invólucro de texto em torno exatamente desses bytes. A questão é qual representação uma ferramenta, um protocolo ou uma plataforma espera, e como reconhecer e converter cada uma.
Visão geral
| DER | PEM | |
|---|---|---|
| O que é | Distinguished Encoding Rules do ASN.1 (ITU-T X.690): tag-length-value binário | Texto da RFC 7468: base64 do DER entre rótulos |
| Começa com | Byte 0x30 (SEQUENCE) em certificados e chaves | -----BEGIN CERTIFICATE-----, -----BEGIN PRIVATE KEY----- etc. |
| Tamanho (certificado P-256, medido) | 389 bytes | 583 bytes (cerca de 4/3, mais quebras de linha e rótulos) |
| Objetos por arquivo | Um | Qualquer número de blocos (cadeias, chave mais certificado) |
| Autodescritivo | Sem rótulo; o tipo vem do contexto | O rótulo nomeia a estrutura |
| Extensões comuns | .der, .cer, .crt (ambíguas) | .pem, .crt, .cer, .key, .csr (ambíguas) |
| Impressão digital | SHA-256 destes bytes | Mesmo valor: as impressões digitais são calculadas sobre o DER interno |
| Seguro em e-mail, YAML, variáveis de ambiente | Não | Sim |
O que é cada um
O DER é a codificação binária canônica de dados ASN.1: cada valor é uma tag, um comprimento e um conteúdo, com exatamente uma codificação válida por valor. É essa propriedade canônica que faz as assinaturas funcionarem: a assinatura de um certificado cobre os bytes DER do seu tbsCertificate, e os verificadores não recodificam nada.
O PEM (cujo nome vem do padrão Privacy-Enhanced Mail, de 1993, e que a RFC 7468 especifica para objetos PKIX) envolve esses bytes em base64 padrão, por convenção com 64 caracteres por linha, entre uma linha BEGIN e uma linha END que nomeiam a estrutura: CERTIFICATE, X509 CRL, CERTIFICATE REQUEST, PUBLIC KEY, PRIVATE KEY, ENCRYPTED PRIVATE KEY, além dos rótulos legados do OpenSSL, RSA PRIVATE KEY e EC PRIVATE KEY. O texto antes, entre ou depois dos blocos é ignorado, e é por isso que funcionam os bundles com comentários e a saída de openssl x509 -text.
Conversão e verificação
O script abaixo, executado com o OpenSSL 3.6.5, cria um certificado descartável e mostra que as duas codificações carregam o mesmo objeto.
#!/bin/sh
dir=$(mktemp -d)
cd "$dir" || exit 1
openssl req -new -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout key.pem \
-subj "/CN=example.com" -days 30 -out cert.pem 2>/dev/null
openssl x509 -in cert.pem -outform DER -out cert.der
printf 'cert.pem %s bytes, cert.der %s bytes\n' "$(wc -c < cert.pem | tr -d ' ')" "$(wc -c < cert.der | tr -d ' ')"
head -1 cert.pem
openssl x509 -in cert.der -inform DER -noout -fingerprint -sha256 | cut -c1-40
openssl x509 -in cert.pem -noout -fingerprint -sha256 | cut -c1-40
cd / && rm -rf "$dir"
cert.pem 583 bytes, cert.der 389 bytes
-----BEGIN CERTIFICATE-----
sha256 Fingerprint=FE:8B:DC:19:30:EE:A8:
sha256 Fingerprint=FE:8B:DC:19:30:EE:A8:
O mesmo padrão vale para chaves (openssl pkey -in key.pem -outform DER), CSRs (openssl req -outform DER) e CRLs (openssl crl -outform DER). Para identificar um arquivo desconhecido: se ele começa com -----BEGIN, é PEM; se xxd file | head -1 mostra 3082 perto do início, é quase certamente DER.
Erros típicos
no start line/Expecting: TRUSTED CERTIFICATEno OpenSSL: a ferramenta esperava PEM e recebeu DER, ou um bloco PEM com outro rótulo. Adicione-inform DERou confira o rótulo.header too long/wrong tag: a ferramenta esperava DER e recebeu texto PEM, ou um arquivo truncado.- Quebras de linha do Windows ou espaços soltos dentro de um bloco PEM colado em um formulário web ou em YAML; parsers estritos os rejeitam. Recodifique em vez de editar à mão.
- Um bundle PEM onde se esperava um único certificado: muitas ferramentas leem apenas o primeiro bloco, então a ordem importa (nos servidores, o certificado folha vem primeiro).
- Base64url em vez de base64: o PEM usa o alfabeto padrão, com
+,/e padding; o JOSE e o WebAuthn usam base64url. Um certificado copiado do membrox5cde uma JWK é DER em base64 padrão, e envolvê-lo nas linhas PEM o transforma em um arquivo PEM válido.
O explorador de ASN.1 aceita qualquer uma das duas codificações e mostra a estrutura, e o divisor de pacotes PEM separa arquivos com vários certificados.
Bundles e cadeias
Como o DER contém exatamente um objeto, tudo o que precisa de vários objetos em um só arquivo usa concatenação de PEM ou um formato de contêiner. O fullchain.pem de um servidor é o certificado folha seguido dos intermediários; um bundle de CAs como /etc/ssl/certs/ca-certificates.crt reúne centenas de certificados raiz em um único arquivo PEM. As alternativas baseadas em DER são os bundles de certificados PKCS #7 (.p7b, um SignedData do CMS sem conteúdo e só com certificados, comum no Windows) e o PKCS #12 (.pfx), quando uma chave privada viaja junto com a cadeia. Para converter um .p7b em PEM, use openssl pkcs7 -print_certs -in bundle.p7b, que grava cada certificado em um bloco PEM próprio.
A ordem e a completude importam mais que a codificação: um servidor deve enviar o certificado folha primeiro, além de todos os intermediários necessários para chegar a uma raiz em que os clientes confiam, e a falta de um intermediário quebra os clientes que não o buscam por conta própria, seja qual for o formato do arquivo.
Quando escolher cada um
- Servidores web, proxies reversos, clientes ACME: PEM (
fullchain.pem,privkey.pem). - Java (
keytool -importcert,CertificateFactory): qualquer um dos dois, mas o DER é a entrada canônica; os keystores usam PKCS #12 para chave mais cadeia. - Importação de certificados no Windows:
.cerem DER ou.cercodificado em PEM; chave mais certificado vão em um.pfx. - Incorporação em código-fonte, variáveis de ambiente, Secrets do Kubernetes: texto PEM (ou DER em base64, se um campo exigir).
- Protocolos de rede e contêineres binários: DER, sempre; TLS, CMS, OCSP e as extensões X.509 nunca transportam PEM.
- Arquivamento e auditoria: DER para armazenamento exato, byte a byte; PEM se pessoas precisarem inspecionar os arquivos.
Notas de migração
Não há nada a migrar no sentido criptográfico; trocar de codificação é um detalhe de implantação.
- Padronize os nomes de arquivo:
.pempara PEM,.derpara DER, e evite as extensões ambíguas.crte.cernas suas próprias ferramentas. - Converta no momento da implantação, mantendo uma única fonte da verdade (normalmente PEM) no seu repositório ou cofre de segredos.
- Confira as impressões digitais depois da conversão com
openssl x509 -noout -fingerprint -sha256; elas devem ser iguais. - Em chaves privadas, mantenha a criptografia ativada:
openssl pkey -outform DERgrava uma chave não criptografada, a menos que você passe uma cifra, e as ferramentas costumam manipular chaves DER com menos avisos. - Documente os formatos esperados na configuração (
ssl_certificateespera PEM; os truststores do Java esperam DER ou PKCS #12), já que a maioria dos erros de formato vem de suposições.