Saltar al contenido
ecdsa.com

PEM frente a DER: el mismo certificado en texto o binario

DER es la codificación binaria de ASN.1 en la que se definen los certificados y las claves. PEM es ese mismo DER, codificado en base64 entre las líneas BEGIN y END. La conversión no cambia nada del contenido.

PEM frente a DER no es una elección entre datos distintos: un certificado, una clave, una CSR o una CRL se definen siempre como ASN.1 codificado en DER, y PEM es un envoltorio de texto alrededor de esos mismos bytes. La cuestión es qué representación espera una herramienta, un protocolo o una plataforma, y cómo reconocer y convertir cada una.

De un vistazo

DERPEM
Qué esDistinguished Encoding Rules de ASN.1 (ITU-T X.690): etiqueta, longitud y valor en binarioTexto del RFC 7468: base64 de DER entre etiquetas
Empieza porEl byte 0x30 (SEQUENCE) en certificados y claves-----BEGIN CERTIFICATE-----, -----BEGIN PRIVATE KEY-----, etc.
Tamaño (certificado P-256, medido)389 bytes583 bytes (unos 4/3 más los saltos de línea y las etiquetas)
Objetos por archivoUnoCualquier número de bloques (cadenas, clave más certificado)
AutodescriptivoSin etiqueta; el tipo se deduce del contextoLa etiqueta nombra la estructura
Extensiones habituales.der, .cer, .crt (ambiguas).pem, .crt, .cer, .key, .csr (ambiguas)
Huella digitalSHA-256 de estos bytesEl mismo valor: las huellas se calculan sobre el DER del interior
Seguro en correo electrónico, YAML, variables de entornoNoSí

Qué es cada uno

DER es la codificación binaria canónica de los datos ASN.1: cada valor es una etiqueta, una longitud y un contenido, con exactamente una codificación válida por valor. Esa propiedad canónica es lo que hace que las firmas funcionen: la firma de un certificado cubre los bytes DER de su tbsCertificate, y los verificadores no vuelven a codificar nada.

PEM —que toma su nombre del estándar Privacy-Enhanced Mail (correo con privacidad mejorada) de 1993 y que el RFC 7468 especifica para los objetos PKIX— envuelve esos bytes en base64 estándar, por convención con 64 caracteres por línea, entre una línea BEGIN y una línea END que nombran la estructura: CERTIFICATE, X509 CRL, CERTIFICATE REQUEST, PUBLIC KEY, PRIVATE KEY, ENCRYPTED PRIVATE KEY, además de las etiquetas heredadas de OpenSSL RSA PRIVATE KEY y EC PRIVATE KEY. El texto antes, entre o después de los bloques se ignora, y gracias a eso funcionan los bundles con comentarios y la salida de openssl x509 -text.

Conversión y comprobación

El script siguiente, ejecutado con OpenSSL 3.6.5, crea un certificado desechable y muestra que ambas codificaciones contienen el mismo objeto.

OpenSSL: un certificado en PEM y en DER
#!/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"
Salida
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:

El mismo patrón se aplica a las claves (openssl pkey -in key.pem -outform DER), las CSR (openssl req -outform DER) y las CRL (openssl crl -outform DER). Para identificar un archivo desconocido: si empieza por -----BEGIN, es PEM; si xxd file | head -1 muestra 3082 cerca del principio, es casi seguro DER.

Errores típicos

  • no start line / Expecting: TRUSTED CERTIFICATE de OpenSSL: la herramienta esperaba PEM y recibió DER, o un bloque PEM con otra etiqueta. Añade -inform DER o comprueba la etiqueta.
  • header too long / wrong tag: la herramienta esperaba DER y recibió texto PEM, o un archivo truncado.
  • Finales de línea de Windows o espacios sueltos dentro de un bloque PEM pegado en un formulario web o en YAML; los analizadores estrictos los rechazan. Vuelve a codificarlo en lugar de editarlo a mano.
  • Un bundle PEM donde se esperaba un solo certificado: muchas herramientas solo leen el primer bloque, así que el orden importa (en los servidores, primero el certificado hoja).
  • Base64url en lugar de base64: PEM usa el alfabeto estándar con +, / y relleno; JOSE y WebAuthn usan base64url. Un certificado copiado del miembro x5c de una JWK es DER en base64 estándar, y envolverlo en líneas PEM lo convierte en un archivo PEM válido.

El explorador de ASN.1 acepta cualquiera de las dos codificaciones y muestra la estructura, y el divisor de bundles PEM separa los archivos con varios certificados.

Bundles y cadenas

Como DER contiene exactamente un objeto, todo lo que necesita varios objetos en un archivo usa la concatenación de PEM o un formato contenedor. El fullchain.pem de un servidor es el certificado hoja seguido de los intermedios; un bundle de CA como /etc/ssl/certs/ca-certificates.crt reúne cientos de certificados raíz en un solo archivo PEM. Las alternativas basadas en DER son los bundles de certificados PKCS #7 (.p7b, un SignedData de CMS sin contenido y solo con certificados, habitual en Windows) y PKCS #12 (.pfx) cuando una clave privada viaja con la cadena. Para convertir un .p7b a PEM se usa openssl pkcs7 -print_certs -in bundle.p7b, que escribe cada certificado como un bloque PEM propio.

El orden y la completitud importan más que la codificación: un servidor debe enviar primero su certificado hoja y todos los intermedios necesarios para llegar a una raíz en la que confíen los clientes, y si falta un intermedio, fallan los clientes que no lo descargan por sí mismos, sea cual sea el formato del archivo.

Cuándo elegir cada uno

  • Servidores web, proxies inversos, clientes ACME: PEM (fullchain.pem, privkey.pem).
  • Java (keytool -importcert, CertificateFactory): cualquiera de los dos, aunque DER es la entrada canónica; los almacenes de claves usan PKCS #12 para la clave junto con la cadena.
  • Importación de certificados en Windows: .cer en DER o .cer codificado en PEM; la clave junto con el certificado va en un .pfx.
  • Inserción en código fuente, variables de entorno, secretos de Kubernetes: texto PEM (o DER en base64, si un campo lo exige).
  • Protocolos de red y contenedores binarios: DER, siempre; TLS, CMS, OCSP y las extensiones X.509 nunca transportan PEM.
  • Archivado y auditoría: DER para un almacenamiento exacto byte a byte; PEM si las personas necesitan inspeccionar los archivos.

Notas de migración

No hay nada que migrar en sentido criptográfico; cambiar de codificación es un detalle del despliegue.

  1. Unifica los nombres de archivo: .pem para PEM, .der para DER, y evita las ambiguas .crt y .cer en tus propias herramientas.
  2. Convierte en el momento del despliegue, con una única fuente de verdad (normalmente PEM) en tu repositorio o tu almacén de secretos.
  3. Comprueba las huellas digitales después de la conversión con openssl x509 -noout -fingerprint -sha256; deben coincidir.
  4. En las claves privadas, mantén el cifrado: openssl pkey -outform DER escribe una clave sin cifrar a menos que indiques un algoritmo de cifrado, y las herramientas que manejan claves DER suelen mostrar menos advertencias.
  5. Documenta los formatos esperados en la configuración (ssl_certificate espera PEM; los almacenes de confianza de Java esperan DER o PKCS #12), ya que la mayoría de los errores de formato vienen de suponerlos.

Referencias

Todas las comparaciones