OpenSSL es la navaja suiza de la gestión de certificados SSL/TLS. Tanto si necesitas generar una clave privada, inspeccionar un certificado próximo a vencer, crear una Autoridad Certificadora para servicios internos o depurar un fallo en el protocolo de enlace TLS, el CLI de openssl lo gestiona todo. Esta guía te lleva por todas las operaciones esenciales de certificados — desde la generación de claves hasta la validación de la cadena — con comandos prácticos que puedes ejecutar de inmediato en cualquier servidor Linux.
Requisitos Previos
- OpenSSL instalado (versión 1.1.x o 3.x — verifica con
openssl version) - Familiaridad básica con la línea de comandos de Linux
- Acceso root o sudo si instalas certificados a nivel de sistema
- Comprensión de qué son los certificados SSL/TLS (pares de claves pública/privada, CAs, cadenas de confianza)
Generación de Claves y Solicitudes de Firma de Certificado
Todo ciclo de vida de un certificado comienza con una clave privada. OpenSSL admite RSA, ECDSA y Ed25519. RSA de 4096 bits y ECDSA P-256 son las opciones más comunes para producción.
Generar una clave privada RSA:
openssl genrsa -out key.pem 4096
Generar una clave ECDSA (más rápida, más pequeña, igualmente segura):
openssl ecparam -genkey -name prime256v1 | openssl ec -out ec-key.pem
Crear una Solicitud de Firma de Certificado (CSR):
openssl req -new -key key.pem -out request.csr
Se te pedirán los campos del Nombre Distinguido (DN). El campo más crítico es Common Name (CN) — debe coincidir con tu nombre de dominio. Para TLS moderno, se requieren los Nombres Alternativos del Sujeto (SANs). Usa un archivo de configuración para establecerlos:
cat > san.conf <<EOF
[req]
req_extensions = v3_req
distinguished_name = dn
[dn]
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
DNS.2 = www.example.com
EOF
openssl req -new -key key.pem -out request.csr -config san.conf
Inspeccionar el CSR antes de enviarlo:
openssl req -text -noout -in request.csr
Creación de Certificados Autofirmados
Los certificados autofirmados son ideales para servicios internos, entornos de desarrollo y APIs privadas donde una CA pública no es necesaria.
Crear un certificado autofirmado en un solo comando:
openssl req -x509 -newkey rsa:4096 \
-keyout key.pem -out cert.pem \
-sha256 -days 365 -nodes \
-subj "/CN=example.com/O=MyOrg/C=US"
El indicador -nodes omite el cifrado de contraseña en la clave privada. Eliminarlo para claves almacenadas fuera de línea.
Autofirmado con SANs (requerido por navegadores modernos):
openssl req -x509 -newkey rsa:4096 \
-keyout key.pem -out cert.pem \
-sha256 -days 365 -nodes \
-subj "/CN=example.com" \
-addext "subjectAltName=DNS:example.com,DNS:www.example.com"
Creación de una Autoridad Certificadora Interna
Una CA interna te permite emitir certificados de confianza para todos los servicios dentro de tu organización sin depender de una CA pública.
Crear la clave de CA y el certificado raíz autofirmado:
openssl genrsa -aes256 -out ca-key.pem 4096
openssl req -new -x509 -days 3650 \
-key ca-key.pem -out ca-cert.pem \
-subj "/CN=My Internal CA/O=MyOrg/C=US"
Firmar un CSR de servidor con tu CA:
openssl x509 -req -days 365 \
-in request.csr \
-CA ca-cert.pem -CAkey ca-key.pem \
-CAcreateserial -out server-cert.pem \
-extfile san.conf -extensions v3_req
Inspección y Validación de Certificados
Leer un certificado local:
openssl x509 -text -noout -in cert.pem
Verificar solo la fecha de expiración:
openssl x509 -enddate -noout -in cert.pem
Inspeccionar el certificado de un servidor remoto:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -text -noout
Verificar que el certificado coincide con la clave privada:
openssl rsa -noout -modulus -in key.pem | md5sum
openssl x509 -noout -modulus -in cert.pem | md5sum
Comparativa
| Característica | OpenSSL CLI | cfssl | easy-rsa | certbot |
|---|---|---|---|---|
| Certificados autofirmados | Sí | Sí | Sí | No |
| CA interna | Sí | Sí | Sí | No |
| Integración con CA pública | No | No | No | Sí (Let’s Encrypt) |
| Soporte SAN | Sí (archivo config) | Sí | Sí | Sí |
| Exportación PKCS#12 | Sí | Parcial | No | Sí |
| Curva de aprendizaje | Media | Baja | Baja | Muy baja |
Escenario del Mundo Real
Tienes un servidor Nginx de producción que muestra errores de protocolo de enlace SSL. Los usuarios reportan “NET::ERR_CERT_COMMON_NAME_INVALID” en Chrome. Este es el flujo de diagnóstico:
# Paso 1: verificar qué certificado está sirviendo el servidor
echo | openssl s_client -connect myserver.com:443 -servername myserver.com 2>/dev/null \
| openssl x509 -text -noout | grep -A3 "Subject Alternative Name"
# Paso 2: si no hay SANs, regenerar con el enfoque san.conf
# Paso 3: verificar coincidencia clave/certificado tras la regeneración
openssl rsa -noout -modulus -in /etc/nginx/ssl/key.pem | md5sum
openssl x509 -noout -modulus -in /etc/nginx/ssl/cert.pem | md5sum
# Paso 4: probar el protocolo de enlace completo
openssl s_client -connect myserver.com:443 -servername myserver.com
Errores Comunes y Casos Especiales
Los SANs son obligatorios desde 2017. Chrome 58 dejó de admitir certificados solo con CN. Siempre incluye subjectAltName incluso para certificados de un solo dominio.
Los permisos del archivo de clave importan. La clave privada debe ser legible solo por el proceso que la necesita: chmod 600 key.pem. Nginx y Apache rechazarán el arranque si la clave es legible para todos.
Las claves con contraseña bloquean los reinicios automáticos. Usa -nodes al generar claves para servidores web.
El orden de la cadena de certificados importa. Nginx y Apache esperan primero el certificado del servidor, seguido de los certificados intermedios, en el mismo archivo PEM.
La desincronización horaria rompe la validación. Si el reloj del servidor está desfasado más de unos minutos, openssl verify fallará con “certificate not yet valid”.
Exportar al formato PKCS#12 para Windows/Java:
openssl pkcs12 -export \
-out bundle.p12 \
-inkey key.pem \
-in cert.pem \
-certfile ca-cert.pem
Solución de Problemas
“verify error:num=20:unable to get local issuer certificate” — El certificado de CA no está en tu almacén de confianza. Pásalo explícitamente: openssl verify -CAfile ca-cert.pem cert.pem.
“private key does not match the certificate public key” — Los hashes del módulo difieren. Regeneraste la clave sin regenerar el certificado o confundiste archivos.
“no shared cipher” — El cliente y el servidor no pueden acordar un conjunto de cifrado. Revisa la configuración SSL del servidor.
“certificate has expired” — Verifica con openssl x509 -enddate -noout -in cert.pem y renueva con el mismo CSR.
Resumen
- Genera claves RSA 4096 o ECDSA P-256 con
openssl genrsaoopenssl ecparam - Siempre incluye Subject Alternative Names — los certificados solo con CN son rechazados por navegadores modernos
- Usa un archivo de configuración con sección
[alt_names]para agregar SANs a CSRs y certificados autofirmados - Inspecciona cualquier certificado con
openssl x509 -text -noout -in cert.pem - Verifica la coincidencia clave/certificado comparando los hashes MD5 del módulo
- Crea una CA interna para Kubernetes, VPN y microservicios sin dependencias externas
- Exporta al formato PKCS#12 para almacenes de claves Java y almacenes de certificados de Windows
- Mantén las claves privadas de CA cifradas, fuera de línea y con copias de seguridad separadas