OpenSSL es la herramienta de referencia para generar claves privadas, solicitudes de firma de certificado (CSR) y certificados X.509, tanto autofirmados para entornos de desarrollo como para enviar a una autoridad certificadora. Los comandos que lo componen (`req`, `x509`, `s_client`, `genrsa`) tienen una sintaxis densa y con muchos parámetros interdependientes, y un solo flag olvidado (como `-nodes` o el `-newkey` correcto) produce un archivo que no sirve para lo que necesitabas. Este generador de comandos OpenSSL construye la línea exacta según lo que quieras conseguir —clave y CSR, certificado autofirmado, o inspección de un certificado existente— evitando la memorización de decenas de flags poco intuitivos.
Clave privada, CSR y certificado: tres artefactos distintos
La clave privada (.key o .pem) es el secreto que nunca sale del servidor y con el que se firman las conexiones TLS. El CSR (Certificate Signing Request) es un documento que contiene la clave pública y los datos del solicitante (dominio, organización, país) firmado con la clave privada, y se envía a una autoridad certificadora para que emita el certificado final. El certificado (.crt) es lo que la CA devuelve tras validar el CSR: contiene la clave pública, los datos del titular y la firma de la CA, y es lo que el servidor presenta a los clientes durante el handshake TLS. Confundir estos tres archivos es el error más común al configurar HTTPS manualmente: instalar el CSR en lugar del certificado, o exponer la clave privada en un repositorio, invalida toda la cadena de confianza.
Generar un certificado autofirmado para desarrollo
Para entornos locales o de pruebas, openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/C=ES/ST=Madrid/L=Madrid/O=Ejemplo SL/CN=app.ejemplo.com" genera en un solo comando la clave privada RSA de 2048 bits y un certificado autofirmado válido durante 365 días, sin pedir contraseña para la clave gracias a -nodes (no encriptar la clave privada, útil para que un servicio pueda leerla sin intervención manual al arrancar). Este certificado no lo valida ningún navegador por defecto —mostrará advertencia de "conexión no privada"— porque la firma la ha hecho la propia clave y no una CA reconocida por el sistema operativo o el navegador.
El campo Subject Alternative Name (SAN), obligatorio hoy
Desde 2017, los navegadores modernos ignoran el Common Name (CN) del certificado y exigen que el dominio figure en la extensión subjectAltName (SAN). Para incluirlo hay que añadir -addext "subjectAltName=DNS:app.ejemplo.com,DNS:www.app.ejemplo.com,IP:192.168.1.10" al comando req, o definir una sección [alt_names] en un archivo de configuración OpenSSL cuando el certificado debe cubrir varios dominios o subdominios. Un certificado generado sólo con CN y sin SAN produce el error ERR_CERT_COMMON_NAME_INVALID en Chrome y equivalentes en otros navegadores, aunque el CN coincida exactamente con el dominio visitado.
Inspeccionar un certificado existente
openssl x509 -in cert.pem -noout -text vuelca la estructura completa del certificado: número de serie, algoritmo de firma, emisor, sujeto, periodo de validez y extensiones como el SAN o el uso de clave permitido. Para una consulta rápida sin todo el detalle, -noout -subject -dates muestra sólo el titular y las fechas de validez, ideal para un script que compruebe automáticamente si un certificado está a punto de caducar. -noout -fingerprint -sha256 calcula la huella digital SHA-256 del certificado, útil para verificar que dos copias del mismo archivo (por ejemplo, en dos servidores de un balanceador) son idénticas.
Probar una conexión TLS en vivo con s_client
openssl s_client -connect ejemplo.com:443 -servername ejemplo.com abre una conexión TLS real contra el servidor indicado (el flag -servername es imprescindible cuando el servidor usa SNI para servir varios certificados en la misma IP) y vuelca la cadena de certificados presentada, el protocolo TLS negociado y el resultado de la verificación (Verify return code: 0 (ok) si la cadena es válida hasta una CA de confianza del sistema). Añadiendo -cipherlist o revisando el bloque Cipher de la salida se comprueba qué suite criptográfica ha negociado el servidor, y echo | openssl s_client ... 2>/dev/null | openssl x509 -noout -dates es un one-liner habitual para comprobar la caducidad de un certificado remoto sin descargarlo a mano.
Tamaño de clave y algoritmo: RSA frente a ECDSA
RSA de 2048 bits es el mínimo aceptado hoy por la mayoría de CAs y navegadores; RSA de 4096 bits añade margen de seguridad a costa de operaciones de firma más lentas, relevante en servidores con mucho tráfico TLS. ECDSA con la curva P-256 (openssl ecparam -genkey -name prime256v1) ofrece seguridad equivalente a RSA de 3072 bits con claves y firmas mucho más pequeñas, lo que reduce el tamaño del handshake TLS y mejora la latencia percibida, especialmente en conexiones móviles. La contrapartida es que algunos sistemas muy antiguos no soportan ECDSA, por lo que muchos despliegues de doble certificado sirven RSA y ECDSA en paralelo según lo que el cliente anuncie soportar durante el handshake.
Renovación y automatización con Let's Encrypt
Para producción, un certificado autofirmado no sirve porque ningún navegador confía en él por defecto; la alternativa gratuita y automatizable es Let's Encrypt vía el protocolo ACME, normalmente con el cliente certbot, que genera la clave, construye el CSR, valida la propiedad del dominio (por HTTP o por DNS) y descarga el certificado firmado, todo en un solo comando. Los certificados de Let's Encrypt caducan a los 90 días, un plazo corto deliberado para forzar la automatización de la renovación; certbot renew comprueba qué certificados están a menos de 30 días de caducar y los renueva, y conviene programarlo como timer de systemd (no como cron simple) para tener registro de éxito o fallo en journalctl.
Salidas reales de ejemplo
.....+...+++++++++++++++++++++++++++++++++++++++*.+...+++++++++++++++++++++++++++++++++++++++*....
.+.+........+....+...+.........+.....+....+..........................+...+.+++++++++++++++++++++++++++++++++++++++*
-----Salida real del comando: primero el progreso de generación de la clave RSA, sin prompts porque -subj y -nodes evitan las preguntas interactivas.
subject=C=ES, ST=Madrid, L=Madrid, O=Ejemplo SL, CN=app.ejemplo.com
notBefore=Sep 6 17:43:26 2026 GMT
notAfter=Sep 6 17:43:26 2027 GMT
issuer=C=ES, ST=Madrid, L=Madrid, O=Ejemplo SL, CN=app.ejemplo.comConfirma el titular exacto del certificado y su ventana de validez; útil para scripts de comprobación de caducidad.
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
2c:03:ef:54:7f:3c:da:c9:29:b6:a9:1d:56:3b:78:d7:ea:5c:4a:d6
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=ES, ST=Madrid, L=Madrid, O=Ejemplo SL, CN=app.ejemplo.com
Validity
Not Before: Sep 6 17:43:26 2026 GMT
Not After : Sep 6 17:43:26 2027 GMT
Subject: C=ES, ST=Madrid, L=Madrid, O=Ejemplo SL, CN=app.ejemplo.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)El bloque Data muestra el número de serie, el algoritmo de firma y la clave pública RSA de 2048 bits generada.
CONNECTED(00000003)
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = ejemplo.com
verify return:1
---
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
---
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
Verify return code: 0 (ok)El campo Verify return code confirma si la cadena de certificados es válida hasta una CA de confianza del sistema.
Algoritmos de clave para certificados TLS
| Algoritmo | Tamaño equivalente de seguridad | Velocidad de firma | Compatibilidad |
|---|---|---|---|
| RSA 2048 | Nivel base aceptado hoy | Más lenta | Máxima, incluye clientes muy antiguos |
| RSA 4096 | Margen extra sobre RSA 2048 | Notablemente más lenta | Máxima, pero handshake más pesado |
| ECDSA P-256 | Equivalente a RSA ~3072 | Rápida | Alta en clientes modernos (2015+) |
Elección entre compatibilidad máxima y eficiencia en el handshake.
Casos de uso comunes
- Generar un certificado autofirmado para probar HTTPS en un entorno de desarrollo local
- Crear un CSR para enviarlo a una CA comercial o interna de la empresa
- Comprobar desde línea de comandos cuándo caduca el certificado de un dominio en producción
- Diagnosticar un fallo de handshake TLS verificando la cadena de certificados con s_client
- Verificar que la clave privada y el certificado instalados en el servidor coinciden entre sí
Buenas prácticas
- Nunca subas la clave privada (`.key`) a un repositorio; trátala igual que cualquier otro secreto
- Incluye siempre `subjectAltName` en el CSR; los navegadores modernos ignoran el CN si falta el SAN
- Usa RSA de al menos 2048 bits o ECDSA P-256; evita claves de 1024 bits, obsoletas e inseguras
- Automatiza la renovación de certificados de Let's Encrypt con un timer de systemd, no con cron a ciegas
- Verifica la caducidad de certificados en producción de forma periódica con un script que use `openssl x509 -checkend`
- Comprueba con `openssl x509 -noout -modulus` que la clave privada y el certificado corresponden al mismo par