Leer un certificado SSL/TLS o una CSR: fechas, dominios, emisor y huellas

Pega un certificado SSL/TLS o una solicitud de firma (CSR) en formato PEM, o elige el archivo .crt, .pem, .cer o .csr, y verás para qué dominios vale, quién lo emitió, cuándo caduca y cuántos días le quedan, el tipo de clave, sus usos y sus huellas SHA-256 y SHA-1. Si pegas una cadena completa, comprueba también que esté en orden. Todo se lee en tu navegador.

Pega solo certificados y solicitudes, nunca la clave privada (el bloque -----BEGIN PRIVATE KEY-----). Los certificados son públicos: cualquier navegador los recibe al entrar en el sitio. La clave privada no, y con ella cualquiera podría hacerse pasar por tu servidor. Si la pegas aquí por error, la herramienta la ignora y te avisa.

Qué muestra de cada certificado

  • Sujeto y nombres alternativos (SAN): para quién se emitió. Los navegadores solo miran los SAN de tipo DNS o IP; el nombre común (CN) se ignora desde hace años, así que un certificado sin SAN da error aunque el CN coincida.
  • Emisor: la autoridad de certificación (CA) que lo firmó. Si es igual al sujeto, el certificado es autofirmado.
  • Validez: las fechas de inicio y fin, en UTC, la duración y los días que le quedan contados desde ahora.
  • Clave pública y firma: RSA (con sus bits), curva elíptica (P-256, P-384…) o Ed25519, y el algoritmo con que la CA lo firmó. Avisa si la firma usa SHA-1 o MD5, o si la clave RSA tiene menos de 2048 bits.
  • Usos: el uso de la clave (firma digital, cifrado de claves, firmar certificados…) y el uso extendido, que dice si sirve para un servidor web, un cliente, firmar código o correo.
  • Si es una CA: las restricciones básicas dicen si puede firmar otros certificados y cuántos niveles por debajo.
  • Revocación y transparencia: las direcciones de OCSP y de la lista de revocación, y cuántas marcas SCT de los registros públicos de Certificate Transparency lleva.
  • Huellas: el SHA-256 y el SHA-1 del certificado entero, que identifican un certificado concreto, y el pin de la clave: el SHA-256 en Base64 de la clave pública, que no cambia al renovar si se conserva la misma clave.

Para entender cómo encajan la CA raíz, los intermedios y el certificado del sitio, y por qué el navegador confía en ellos, lee nuestra guía sobre certificados y confianza en internet.

Cómo conseguir el certificado de un sitio

  • Desde el navegador: pulsa el candado o el icono de la izquierda de la dirección, entra en los detalles del certificado y expórtalo en formato PEM (Firefox ofrece «PEM (cert)» y «PEM (cadena)»).
  • Con OpenSSL: openssl s_client -connect sitio.com:443 -servername sitio.com -showcerts </dev/null imprime la cadena que entrega el servidor. Copia los bloques entre BEGIN y END y pégalos aquí. La herramienta ignora el texto de alrededor.
  • De tu servidor: en nginx o Apache, el archivo que indica ssl_certificate o SSLCertificateFile, que suele llamarse fullchain.pem si es de Let’s Encrypt.

Si el archivo es binario (DER, habitual con extensión .cer en Windows), elígelo con el botón: la herramienta lo detecta. Para convertirlo a PEM: openssl x509 -inform der -in cert.cer -out cert.pem.

Cuánto pueden durar los certificados TLS

Los navegadores y las CA, reunidos en el CA/Browser Forum, fijan la duración máxima de los certificados TLS públicos, y la están recortando para que una clave robada o un error de emisión sirva el menor tiempo posible:

  • Desde el 1 de septiembre de 2020: 398 días como máximo.
  • Desde el 15 de marzo de 2026: 200 días.
  • Desde el 15 de marzo de 2027: 100 días.
  • Desde el 15 de marzo de 2029: 47 días.

Con plazos así, renovar a mano deja de ser práctico: lo normal es automatizarlo con ACME, el protocolo de Let’s Encrypt, que ya admiten la mayoría de las CA. Los certificados de una CA privada, como los de una red interna, no tienen estos límites.

Comprobar en Python cuándo caduca un certificado

Solo con la biblioteca estándar: se conecta al servidor, valida el certificado como lo haría un navegador y dice cuántos días le quedan. Sirve para una tarea programada que avise antes de que caduque:

import hashlib
import socket
import ssl
import time


def revisar(host, puerto=443):
    """Se conecta al servidor, valida su certificado como un navegador y dice cuándo caduca."""
    contexto = ssl.create_default_context()           # usa las CA de confianza del sistema
    with socket.create_connection((host, puerto), timeout=10) as s:
        with contexto.wrap_socket(s, server_hostname=host) as tls:
            cert = tls.getpeercert()                  # ya validado: si no, salta ssl.SSLCertVerificationError
            der = tls.getpeercert(binary_form=True)
    sujeto = dict(x[0] for x in cert["subject"])
    emisor = dict(x[0] for x in cert["issuer"])
    caduca = ssl.cert_time_to_seconds(cert["notAfter"])
    dias = int((caduca - time.time()) // 86400)
    print(f"{host}: {sujeto.get('commonName')}, emitido por {emisor.get('organizationName')}")
    print("  nombres:", ", ".join(v for t, v in cert.get("subjectAltName", ()) if t == "DNS"))
    print(f"  caduca: {cert['notAfter']} (quedan {dias} días)")
    print("  SHA-256:", hashlib.sha256(der).hexdigest().upper()[:47] + "…")
    return dias


for sitio in ["decodigo.com", "www.python.org"]:
    if revisar(sitio) < 30:
        print("  ¡Renuévalo ya!")
$ python3 certificado.pydecodigo.com: decodigo.com, emitido por GoDaddy.com
  nombres: decodigo.com, www.decodigo.com
  caduca: Apr  1 05:12:48 2027 GMT (quedan 154 días)
  SHA-256: 8838F04A2C6AC506A08422354DF5C65610D6E386D81F039…
www.python.org: www.python.org, emitido por GlobalSign nv-sa
  nombres: www.python.org, *.python.org, python.org
  caduca: Feb 14 13:03:45 2027 GMT (quedan 108 días)
  SHA-256: A162964CFE4209E308F700E88028757EB83D227B2BB35F6…

Otras herramientas para desarrolladores: generar hash SHA-256, codificar Base64, decodificador de JWT y calculadora de subredes. Todas, en decodigo.com/herramientas.

Formatos: RFC 5280 (certificados X.509), RFC 2986 (CSR, PKCS #10), RFC 7468 (PEM), ITU-T X.690 (DER) y RFC 6962 (Certificate Transparency). Duración máxima: Baseline Requirements del CA/Browser Forum y la votación SC-081v3 (abril de 2025). El lector se comparó con la biblioteca cryptography de Python en 400 certificados y solicitudes generados al azar (claves RSA, de curva elíptica, Ed25519, Ed448 y DSA; firmas PKCS #1 y PSS; nombres en UTF-8, BMPString y UniversalString; fechas de 1955 a 2080): coinciden los 9,904 campos comparados.