Loading...

Seguridad · 13 min de lectura

¿Qué es TLS? El handshake, TLS 1.3 y los certificados, explicados

TLS (Transport Layer Security) es el protocolo que cifra la conexión entre un navegador y un servidor y demuestra que el servidor es quien dice ser. Es la "S" de HTTPS y el sucesor de SSL. Las versiones en uso hoy son TLS 1.2 y TLS 1.3; la más nueva conecta en un solo viaje de ida y vuelta.

Actualizado

¿Qué es TLS? El handshake, TLS 1.3 y los certificados, explicados

TLS y SSL: un mismo trabajo, dos nombres

TLS (Transport Layer Security) se sitúa entre TCP y HTTP y convierte una conexión en claro en una conexión privada. Cuando una dirección empieza por https://, lo que la hace segura es TLS; el mismo protocolo protege el correo, DNS over TLS y la mayoría de las API.

SSL (Secure Sockets Layer) es donde empezó todo. Netscape publicó SSL 2.0 en 1995 y SSL 3.0 en 1996. Cuando el IETF se hizo cargo del protocolo, le cambió el nombre: TLS 1.0 (1999) es, en esencia, SSL 3.1. Después llegaron TLS 1.1 (2006), TLS 1.2 (2008) y TLS 1.3 (2018).

Todas las versiones de SSL están hoy prohibidas. SSL 3.0 cayó con el ataque POODLE en 2014 y se prohibió formalmente en 2015; TLS 1.0 y 1.1 quedaron obsoletos en 2021, cuando los navegadores ya los habían retirado. Lo que se usa hoy es TLS 1.2 y TLS 1.3.

El nombre antiguo sobrevive en el lenguaje cotidiano. Cuando alguien dice "certificado SSL" se refiere al certificado que presenta un servidor TLS; no existe un certificado SSL distinto de uno TLS. Es el mismo archivo X.509 y funciona con la versión del protocolo que acuerden las dos partes. Si lo que buscas es el certificado en sí, empieza por los certificados SSL gratuitos.

Qué garantiza TLS y qué no

TLS aporta tres propiedades a una conexión.

Confidencialidad. Todo lo que sigue al handshake se cifra con claves que solo conocen los dos extremos. Quien esté en la misma wifi, en el proveedor de internet o en un enlace intermedio solo ve bytes cifrados.

Integridad. Cada registro lleva una etiqueta de autenticación. Si alguien cambia un solo byte por el camino, se detecta, y la conexión se cierra en lugar de entregar datos alterados a la aplicación.

Autenticación. El servidor demuestra que posee la clave privada de un certificado emitido para el nombre que pidió el navegador. Eso es lo que impide que un atacante responda sin más en tu lugar. También se puede autenticar al cliente, con TLS mutuo (mTLS), pero en la web pública es poco habitual.

Igual de útil es saber lo que TLS no hace. No oculta con qué servidor hablas: las direcciones IP son visibles, y también el dominio que viaja en SNI (lo vemos más abajo). No hace seguro el contenido: una inyección SQL llega tan cifrada como un formulario de acceso, y detenerla es trabajo de un WAF. Y solo protege los datos en tránsito: una vez que el servidor los descifra, TLS ya no interviene.

El handshake de TLS 1.2: dos viajes de ida y vuelta

Antes de que se envíe un solo byte de HTTP, navegador y servidor tienen que acordar una versión y un cifrado, comprobar el certificado y derivar claves compartidas. Esa negociación es el handshake TLS, y en TLS 1.2 ocupa dos viajes completos de ida y vuelta además de la conexión TCP.

Primer viaje. El navegador envía ClientHello: las versiones y cipher suites que admite, un valor aleatorio y extensiones como SNI y ALPN (qué versión de HTTP quiere). El servidor responde con ServerHello (la versión y el cifrado elegidos), su cadena de certificados y, con una suite ECDHE, su parte del intercambio de claves firmada con la clave del certificado.

Segundo viaje. El navegador comprueba el certificado, envía su propia parte de la clave y ambos lados calculan las mismas claves de sesión. Después cada uno envía Finished, una suma de comprobación de todo lo intercambiado hasta ese momento: si alguien ha manipulado el handshake, falla justo aquí.

Solo entonces puede salir la primera petición. Si se cuenta también el handshake de TCP, una conexión HTTPS nueva sobre TLS 1.2 gasta tres viajes de ida y vuelta antes de que el navegador pueda siquiera pedir la página. Con 20 ms por viaje nadie lo nota; en una conexión móvil con 150 ms entre visitante y servidor, se acerca al medio segundo. Es una de las razones por las que una CDN termina TLS en el edge y no en un origen lejano: los viajes que necesita el handshake se vuelven cortos.

TLS 1.3: un solo viaje y menos margen de error

TLS 1.3 (RFC 8446, 2018) parte de una observación: el navegador puede adivinar. Casi todos los servidores admiten los mismos pocos grupos de intercambio de claves, así que el navegador envía su parte de la clave dentro del propio ClientHello, sin esperar a que se la pidan.

El servidor elige un cifrado, responde con su propia parte y, desde ese momento, ambos lados tienen las claves. Todo lo que viene después del ServerHello, certificado incluido, ya va cifrado. El navegador comprueba el certificado, envía Finished y coloca su primera petición justo detrás: un viaje de ida y vuelta para TLS, dos en total con TCP. En HTTP/3, donde QUIC lleva TLS 1.3 dentro de su propio handshake, transporte y cifrado juntos ocupan uno solo.

Si la apuesta falla, porque el servidor quiere un grupo para el que el navegador no envió clave, el servidor contesta con un HelloRetryRequest y el handshake cuesta un viaje más. Como prácticamente todos los navegadores ofrecen X25519, es raro.

La otra mitad de TLS 1.3 es lo que eliminó.

Ya no hay intercambio de claves RSA. Todos los handshakes usan (EC)DHE efímero, así que todas las conexiones tienen secreto perfecto hacia adelante: una clave privada robada el año que viene no puede descifrar el tráfico grabado hoy.

Solo quedan cifrados AEAD: AES-GCM y ChaCha20-Poly1305. El modo CBC, RC4, 3DES, SHA-1 y MD5 ni siquiera forman parte del protocolo.

La renegociación y la compresión desaparecieron, y con ellas familias enteras de ataques.

TLS 1.3 también protege contra la degradación de versión: un servidor TLS 1.3 al que se empuja a una versión antigua marca su respuesta, y un cliente TLS 1.3 que ve la marca corta la conexión. Si ambos lados hablan 1.3, lo usan; no hay ningún ajuste de "preferir 1.3" que recordar.

0-RTT y reanudación: el atajo y su precio

Un visitante que ya se conectó antes no necesita el handshake completo. Al final de un handshake de TLS 1.3, el servidor puede darle al navegador un ticket de sesión; la próxima vez el navegador lo presenta y ambos lados se saltan el certificado y el costoso acuerdo de claves. Eso es la reanudación de sesión, y sigue costando un viaje de ida y vuelta.

0-RTT (early data) va un paso más allá. Con el ticket, el navegador cifra su primera petición con claves de la sesión anterior y la envía en el mismo paquete que el ClientHello. El servidor puede responder enseguida, así que la petición no espera a ningún handshake.

El precio es el replay. Los datos tempranos se envían antes de que el servidor haya dicho nada en esta conexión, así que no contienen nada nuevo procedente del servidor. Un atacante que grabe ese primer paquete puede reenviarlo, y el servidor verá dos veces una petición válida. Para un GET de una hoja de estilos es inofensivo; para un POST que hace un pedido, mueve dinero o cambia una contraseña, no. Además, los datos tempranos no tienen secreto hacia adelante: quien consiga más tarde la clave de los tickets puede descifrarlos.

Las reglas salen de ahí. Acepta 0-RTT solo para peticiones idempotentes (GET y HEAD sin efectos secundarios). Haz que el servidor o el proxy marque las peticiones con datos tempranos, con la cabecera Early-Data: 1 y el estado 425 Too Early del RFC 8470, para que la aplicación pueda negarse a actuar sobre ellas. Y no trates 0-RTT como una aceleración gratuita que se activa en todas partes.

El edge de CDN.com.tr no acepta datos tempranos 0-RTT, así que la cuestión del replay nunca llega a tu aplicación. Un visitante que vuelve reanuda la sesión con un handshake TLS de un solo viaje.

Certificados y cadena de confianza

El certificado es la forma en que el servidor demuestra quién es. Vincula una clave pública a uno o varios nombres de dominio, que figuran en su campo Subject Alternative Name, tiene un periodo de validez y lo firma una autoridad de certificación (CA).

Los navegadores no confían directamente en tu certificado. Confían en unas pocas decenas de certificados raíz de su almacén de confianza, y las raíces no firman certificados de sitios web: firman intermedios, y un intermedio firma el tuyo. El navegador tiene que construir un camino desde tu certificado hasta una raíz que conozca: hoja (tu certificado, para www.example.com) → intermedio (el certificado emisor de la CA) → raíz (en el almacén de confianza).

Se espera que el servidor envíe la hoja y los intermedios. Olvidar el intermedio es la configuración rota por excelencia: los navegadores de escritorio a menudo siguen funcionando, porque tienen el certificado que falta en caché o pueden descargarlo, mientras que curl, las apps de Android, los callbacks de pago y los clientes de API fallan con "unable to get local issuer certificate". Si algo funciona en tu navegador pero no desde un servidor, revisa primero la cadena.

Un ejemplo real: el 7 de octubre de 2026, cdn.com.tr servía un certificado de Let's Encrypt firmado por el intermedio YR1, que encadena con ISRG Root YR, y el servidor enviaba además Root YR con firma cruzada de ISRG Root X1, la raíz en la que los navegadores confían desde hace años. La firma cruzada es lo que permite que una raíz recién creada funcione en dispositivos que nunca han oído hablar de ella.

Validez. Los certificados de Let's Encrypt duran 90 días, y todo el sector va en la misma dirección: con las reglas del CA/Browser Forum aprobadas en 2025, la vida máxima de un certificado público bajó a 200 días en marzo de 2026 y será de 47 días en 2029. Renovar ya no es una tarea anual: es un proceso que tiene que funcionar solo.

DV, OV, EV. El nivel de validación indica qué comprobó la CA (solo el control del dominio o también la organización), no la fuerza del cifrado. Un certificado gratuito validado por dominio y un costoso certificado EV producen exactamente la misma conexión TLS.

SNI: muchos sitios HTTPS en una sola IP

El HTTPS de los primeros tiempos tenía un problema del huevo y la gallina. El servidor debe presentar el certificado durante el handshake, pero el dominio que quiere el visitante llega en la cabecera Host de HTTP, después del handshake. Por eso cada sitio HTTPS necesitaba su propia dirección IP.

SNI (Server Name Indication) lo resuelve metiendo el dominio en el ClientHello. El servidor lo lee antes de elegir certificado, y así una sola dirección puede alojar miles de sitios HTTPS, cada uno con su certificado. Todas las CDN y todos los hostings compartidos dependen de ello, y todos los navegadores de la última década lo envían.

Conviene conocer dos consecuencias.

Un cliente sin SNI recibe el certificado por defecto. Clientes muy antiguos, algunos dispositivos embebidos y los scripts que se conectan a una IP sin indicar un nombre de servidor reciben el certificado de reserva del servidor y fallan por nombre no coincidente. Cuando pruebes con openssl, pasa siempre -servername.

SNI no va cifrado. El dominio viaja en texto claro dentro del ClientHello, así que una red puede ver, y filtrar, qué sitio abres aunque no vea la página. Así funcionan los bloqueos basados en SNI. Encrypted Client Hello (ECH) es la extensión que lo oculta, y los navegadores han empezado a incorporarla; hasta que esté en todas partes, da por hecho que el dominio es visible.

Cipher suites: cómo leer los nombres

Una cipher suite nombra los algoritmos que usa una conexión. TLS 1.2 mete cuatro decisiones en un solo nombre.

ECDHE-RSA-AES128-GCM-SHA256 significa: intercambio de claves ECDHE (Diffie-Hellman efímero de curva elíptica, que da secreto hacia adelante), autenticación RSA (el tipo de clave del certificado), cifrado de los datos con AES-128 en modo GCM (un cifrado AEAD: confidencialidad e integridad en un solo paso) y SHA-256 para derivar las claves.

Los nombres de TLS 1.3 son más cortos, porque el intercambio de claves y la firma se negocian por separado, y solo existen cinco suites, de las que tres se usan de verdad: TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384 y TLS_CHACHA20_POLY1305_SHA256. Todas son AEAD y todas incluyen secreto hacia adelante, así que no queda nada que ajustar.

Una buena lista de TLS 1.2 tiene arriba el intercambio ECDHE y los cifrados AEAD, nada que contenga RC4, 3DES, MD5, NULL o EXPORT, y es el servidor quien elige según su propio orden en lugar de seguir el del cliente. Las suites CBC antiguas suelen quedarse al final para clientes muy viejos; si elige el servidor, un navegador moderno nunca acaba en ellas. Un escáner enumera todo lo que el servidor ofrece; para ver lo que una conexión real usa, mira la suite negociada con los comandos del final de esta guía.

ChaCha20-Poly1305 existe para dispositivos sin aceleración AES por hardware, sobre todo teléfonos antiguos, donde por software es más rápido que AES-GCM.

Errores TLS comunes y lo que significan de verdad

ERR_SSL_PROTOCOL_ERROR (Chrome): el handshake se rompió de una forma que el navegador no supo clasificar. Las causas habituales son algo distinto de TLS respondiendo en el puerto 443 (HTTP en claro, un portal cautivo), un antivirus o un equipo de red interceptando la conexión, o un servidor sin certificado para ese dominio. Prueba primero desde otra red; si solo falla en una, el problema no es el servidor.

ERR_SSL_VERSION_OR_CIPHER_MISMATCH, en Firefox SSL_ERROR_NO_CYPHER_OVERLAP: cliente y servidor no comparten ninguna versión ni cipher suite. Hoy casi siempre significa que uno de los dos es muy antiguo, como un dispositivo embebido que solo habla TLS 1.0 o un servidor que sigue configurado para él.

ERR_CERT_COMMON_NAME_INVALID: el certificado no incluye el dominio que has abierto. Típico cuando el DNS ya apunta un subdominio nuevo a un servidor que aún no tiene certificado para él, o cuando falta www en el certificado.

ERR_CERT_DATE_INVALID: el certificado ha caducado o el reloj del visitante está mal. Si lo ve una sola persona, revisa su reloj; si lo ve todo el mundo, la renovación se ha detenido.

unable to get local issuer certificate (curl, OpenSSL y muchos SDK): el servidor no envió su certificado intermedio. Arregla la cadena en el servidor, no el almacén de confianza del cliente.

Un 502 de un proxy o de una CDN mientras el navegador muestra un candado válido: el TLS del visitante estaba bien, pero falló la conexión propia del proxy con tu origen. Es un handshake aparte, con su propio certificado y sus propias versiones; la guía del error 502 Bad Gateway lo explica paso a paso.

Cómo termina CDN.com.tr TLS en el edge

Con tu sitio detrás de CDN.com.tr, la conexión TLS del visitante termina en un servidor edge de CDN.com.tr, no en tu origen: el edge guarda tu certificado y hace el handshake. Lo hace con cada dominio, sin un ajuste por sitio que se pueda olvidar.

Solo TLS 1.2 y TLS 1.3. TLS 1.0 y 1.1 se rechazan en el handshake, no se degradan. El edge elige el cifrado de su propia lista, con el intercambio ECDHE y los cifrados AEAD en cabeza; en nuestra prueba del 7 de octubre de 2026, TLS 1.3 negoció TLS_AES_256_GCM_SHA384 sobre X25519. La política es idéntica para todas las cuentas, y la página de política TLS recoge los detalles que piden los cuestionarios de seguridad.

HTTP/3 en todos los sitios. HTTP/3 funciona sobre QUIC, que lleva TLS 1.3 integrado. Los navegadores lo descubren por la cabecera Alt-Svc y cambian en su siguiente conexión; no hay nada que activar. Más en HTTP/3 e IPv6.

Un certificado por dominio, elegido por SNI. Cada uno de tus dominios se sirve con su propio certificado.

Let's Encrypt, emitido y renovado en tu lugar. Con SSL automático, el certificado se solicita en cuanto tu dominio está verificado y su DNS apunta a nosotros, y se renueva solo 30 días antes de caducar. Si el DNS de tu dominio está en CDN.com.tr, el certificado puede ser un comodín (wildcard) que cubre el dominio raíz y todos los subdominios de primer nivel, validado con un registro DNS. ¿Vas a migrar un sitio en producción? El asistente sin cortes emite ese comodín mediante un registro TXT en tu proveedor DNS actual antes del cambio, y HTTPS funciona desde el primer segundo.

Tu propio certificado cuando lo necesites. Un certificado OV o EV comprado en otro sitio se puede subir y asociar a un dominio, y recibe exactamente la misma política TLS.

Una conexión TLS aparte hacia tu origen. Por defecto, una petición HTTPS también se trae de tu origen por HTTPS, mediante la propia conexión del edge al puerto HTTPS de tu origen. El visitante nunca ve ese handshake; si falla, recibe un 502, no un aviso de certificado.

HSTS cuando estés listo. Cuando todo funcione por HTTPS, el preajuste de seguridad HSTS indica a los navegadores que no vuelvan a intentar HTTP en claro con tu dominio.

Comprueba el TLS de cualquier sitio en un minuto

Cinco comandos responden a la mayoría de las preguntas sobre TLS: qué versión y qué cifrado usa una conexión real, qué cadena envía el servidor, cuándo caduca el certificado, si se rechazan las versiones antiguas y cuánto tarda el handshake. Sustituye www.example.com por tu dominio y no quites -servername: sin él pruebas el certificado por defecto del servidor y no el tuyo.

Versión, cifrado, cadena, caducidad y duración del handshake desde la línea de comandos

# Versión y cifrado negociados
openssl s_client -connect www.example.com:443 -servername www.example.com </dev/null 2>/dev/null | grep -E "Protocol|Cipher is"

# La cadena que envía el servidor: titular (s:) y emisor (i:) de cada certificado
openssl s_client -connect www.example.com:443 -servername www.example.com -showcerts </dev/null 2>/dev/null | grep -E "^ *[0-9]+ s:|^ *i:"

# Cuándo caduca el certificado
openssl s_client -connect www.example.com:443 -servername www.example.com </dev/null 2>/dev/null | openssl x509 -noout -enddate

# TLS 1.1 debe ser rechazado (SECLEVEL=0 evita que tu propio OpenSSL lo rechace antes)
openssl s_client -connect www.example.com:443 -servername www.example.com -tls1_1 -cipher 'DEFAULT:@SECLEVEL=0' </dev/null

# Segundos hasta TCP y hasta TCP + TLS
curl -so /dev/null -w 'tcp %{time_connect}  tls %{time_appconnect}\n' https://www.example.com/

Preguntas frecuentes

¿TLS y SSL son lo mismo?

TLS es el sucesor de SSL. El IETF cambió el nombre del protocolo al hacerse cargo de él en 1999, así que TLS 1.0 es, en la práctica, SSL 3.1. Todas las versiones de SSL están prohibidas hoy; cuando alguien dice "SSL" casi siempre quiere decir TLS, y un "certificado SSL" no es más que el certificado que presenta un servidor TLS.

¿TLS 1.2 sigue siendo seguro?

Sí, si está bien configurado: intercambio ECDHE, cifrados AEAD como AES-GCM o ChaCha20-Poly1305 y nada de RC4, 3DES ni suites de exportación. Los servidores lo siguen ofreciendo junto a TLS 1.3 para clientes antiguos. Las versiones que hay que desactivar son TLS 1.0 y 1.1.

¿TLS 1.3 hace más rápido un sitio?

Hace más rápidas las conexiones nuevas: el handshake ocupa un viaje de ida y vuelta en lugar de dos, lo que ahorra un viaje de red por cada conexión nueva y se nota sobre todo en redes móviles lentas. No acelera la transferencia en sí: con la conexión abierta, TLS 1.2 y 1.3 mueven los datos prácticamente a la misma velocidad.

¿Es seguro activar 0-RTT?

Solo para peticiones que se pueden repetir sin daño. Un atacante que capture datos 0-RTT puede reenviarlos, así que una petición que cambia el estado nunca debe procesarse a partir de datos tempranos. Los servidores que lo aceptan deben limitarlo a métodos seguros y marcar esas peticiones (cabecera Early-Data, estado 425) para que la aplicación pueda rechazarlas. El edge de CDN.com.tr no acepta datos tempranos.

¿Qué es SNI y pueden verlo otros?

Server Name Indication es el dominio que el navegador envía al inicio del handshake para que el servidor elija el certificado correcto; es lo que permite que una sola IP sirva muchos sitios HTTPS. Viaja en texto claro, así que una red puede ver qué sitio abres, aunque no la página ni su contenido. Encrypted Client Hello (ECH) es la extensión que lo oculta.

¿Qué versiones de TLS admite CDN.com.tr?

TLS 1.2 y TLS 1.3 en todos los dominios, además de HTTP/3, que siempre usa TLS 1.3. TLS 1.0 y 1.1 se rechazan. La política es la misma para todas las cuentas y no depende de que uses un certificado automático de Let's Encrypt o subas el tuyo.

¿Tengo que cambiar algo en mi servidor para tener TLS 1.3?

Para tus visitantes, no. Detrás de CDN.com.tr su handshake se hace en el edge, así que reciben TLS 1.3 y HTTP/3 ejecute lo que ejecute tu origen. Tu origen solo participa en la conexión aparte que abre el edge, donde funcionan tanto TLS 1.2 como TLS 1.3.