¿Qué es el fingerprinting TLS JA4 y qué te dice de verdad?
Una huella JA4 describe cómo habla TLS un cliente, antes de que envíe una sola cabecera. Cómo se construye, por qué sustituyó a JA3, qué detecta y dónde deja de ser una prueba.
Lo primero que envía un cliente no es una cabecera. Es un client hello de TLS: una lista de suites de cifrado que admite, las extensiones que quiere, las versiones de protocolo que acepta y el protocolo de aplicación que espera hablar. Todo eso llega en claro, antes de cualquier línea de petición, antes de cualquier User-Agent. Una huella JA4 es un resumen compacto de ese mensaje, y resulta interesante por un motivo: el cliente no la eligió como afirmación sobre sí mismo. Salió de la librería TLS sobre la que está construido.
Eso la convierte en un tipo de señal distinto a todo lo que hay en la capa HTTP. Un User-Agent es una frase que escribe el cliente. Una huella JA4 se parece más a un acento.
Cómo leer la cadena
Un valor JA4 tiene tres partes separadas por guiones bajos:
t13d1516h2_8daaf6152771_b186095e22b6
La primera parte se lee sin consultar nada. t significa TCP, y una q en esa posición
significaría QUIC. 13 es TLS 1.3. d indica que había SNI, o sea que el cliente pidió un
dominio en lugar de conectarse a una IP pelada. 15 es el número de suites de cifrado ofrecidas y
16 el de extensiones. h2 es el valor ALPN, así que este cliente pidió HTTP/2.
La segunda parte es un hash truncado de la lista de cifrados, ordenada. La tercera cubre la lista de extensiones y los algoritmos de firma, también ordenados. Los valores GREASE, esas entradas basura que los navegadores insertan a propósito para mantener honestas a las middleboxes, se eliminan antes de hashear.
Ordenar suena a detalle. Es la razón entera por la que existe el formato.
Por qué JA3 dejó de funcionar
JA3, el predecesor de 2017, hasheaba los mismos campos en el orden en que iban por el cable. Funcionaba mientras las pilas TLS eran predecibles. Luego Chrome introdujo la permutación de extensiones a principios de 2023, barajando el orden de las extensiones de su client hello en cada conexión, y una sola instalación de Chrome pasó a producir un hash JA3 distinto por petición. Las reglas construidas sobre listas de permitidos JA3 pasaron de precisas a inútiles en un ciclo de versión.
JA4 ordena antes de hashear, así que reordenar no cambia nada. Además deja el prefijo legible fuera del hash, con lo que puedes distinguir una conexión QUIC de una TCP, o detectar un cliente que ofrece solo tres suites de cifrado, sin una base de datos de valores conocidos. El resto de la familia JA4+ cubre otras capas: JA4H para cabeceras HTTP, JA4T para opciones TCP, JA4S para la respuesta del servidor. La mayor parte del trabajo de detección usa la variante TLS.
Comprueba qué revela el origen de la conexión
Qué detecta
La versión honesta: JA4 es muy bueno cazando clientes que nunca intentaron pasar desapercibidos.
Un script de Python con requests produce un client hello que ningún navegador produce. El
transporte por defecto de Go en net/http tiene su propia forma reconocible. curl también, una
compilación vieja de OpenSSL también, y el cliente HTTP de la mayoría de los SDK igual. Ninguno se
esconde, simplemente son lo que son, y la huella lo dice aunque la petición se presente como
Chrome 141 en macOS.
Ese desajuste es la parte útil. Por sí sola, una huella de cliente HTTP de Go no indica nada malo. Junto a un User-Agent que dice ser un navegador, te indica que el cliente se describe de forma inexacta, y los motivos para hacerlo casi nunca son inocentes.
Lo mismo vale para los navegadores headless, aunque de forma más débil. Una compilación real de
Chrome y un Chrome dirigido por Playwright comparten pila TLS, así que sus valores JA4 coinciden.
Lo que los separa está en otro sitio: la bandera webdriver, superficies de navegador que faltan,
el ritmo de las peticiones y si el cliente llega a pedir las hojas de estilo y las fuentes que
pediría un navegador. Por eso la huella es una entrada y no el veredicto, algo que ya salió en
las mejores señales para detección de bots.
Dónde deja de ser una prueba
Hay dos límites que importan, y los dos se pasan por alto en la prosa comercial.
Una huella es un grupo, no una identidad. Cada Chrome 141 sobre Windows envía en la práctica el mismo client hello. Eso son millones de personas compartiendo una cadena. Puedes decir "esta conexión vino de algo con la forma de Chrome 141", y no puedes decir nada sobre quién. Trata un valor JA4 como identificador de visitante y te equivocarás constantemente, en las dos direcciones.
Las huellas se pueden copiar. uTLS permite que un programa en Go emita un client hello idéntico byte a byte al de una versión de Chrome elegida. curl-impersonate hace lo mismo con curl. Cualquiera con la motivación de leer un artículo puede hacer que su scraper muestre una huella de navegador perfectamente corriente. Lo que cuesta es esfuerzo, y el esfuerzo es un filtro real: la diferencia entre un script que se molestó y uno que no es la mayor parte de la automatización que hay en internet. Pero un operador decidido supera esta señal, así que cualquier cosa que dependa solo de JA4 lo dejará pasar.
Hay un tercer problema, más silencioso. Los proxies corporativos que inspeccionan TLS reescriben el client hello, así que todos los empleados detrás comparten la huella del proxy en vez de la de su navegador. Bloquea por huella y puedes perder una empresa entera de golpe.
Usarla junto a las demás señales
Lo que aguanta es apilar, no clasificar. Cada señal responde a una pregunta distinta:
| Señal | Pregunta que responde | Falla cuando |
|---|---|---|
| JA4 | ¿Qué pila TLS es esta? | El cliente usa uTLS o está detrás de un proxy que inspecciona |
| Origen de la IP | ¿Desde dónde se conecta? | El operador alquila direcciones residenciales |
| Marcadores headless | ¿Se está dirigiendo un navegador? | El tooling parchea sus propios rastros |
| Coherencia de cabeceras | ¿Encajan entre sí las afirmaciones? | La petición se armó a mano con cuidado |
| DNS inverso y ASN | ¿Es este crawler quien dice ser? | El operador no publica nada verificable |
Lee de arriba abajo la columna "falla cuando" y el punto queda claro: las evasiones son distintas en cada fila. Vencer una es fácil, vencer las cinco a la vez es un proyecto. Una IP de centro de datos más una huella de Go más un User-Agent de Chrome no tiene nada de ambiguo. Una IP residencial con huella real de Chrome y sin rastros headless es probablemente una persona, y merece el trato de tal.
Esta es la lógica sobre la que corre Agentscan. Un POST devuelve una clase, human,
known_bot, ai_agent o malicious_automation, con un valor de confianza y las señales que hay
detrás, JA4 entre ellas. Los veredictos cacheados vuelven en menos de 50 ms, y eso es lo que
permite poner la comprobación en un salto de middleware en lugar de en una revisión de logs a la
mañana siguiente.
Una política que funciona
- Obtén la huella donde termina TLS. El código de la aplicación nunca ve el client hello. Llega desde tu CDN, tu balanceador de carga o una API de detección puesta delante.
- Puntúa el desajuste, no la huella. La señal es "la pila TLS no cuadra con el navegador que dice ser", no "este hash es malo". Mantener una lista de bloqueo de hashes envejece mal, porque cada versión de navegador acuña otros nuevos.
- Nunca la dejes actuar sola. Combínala como mínimo con el origen. Por su cuenta cazará un proxy corporativo y se le escapará un scraper competente, o sea el resultado equivocado dos veces.
- Cuenta con que los valores cambien. Las actualizaciones de navegador cambian los conjuntos de cifrados y extensiones. Lo que fijes hoy necesita una fecha de revisión, o acabará marcando en silencio a usuarios reales.
- Regístrala igualmente. Aunque no actúes sobre ella, guardar el JA4 con cada petición hace legible el siguiente incidente. Ver que 40.000 peticiones compartían una huella poco común es un arranque mucho más rápido que leer logs en bruto.
En resumen
JA4 te dice cómo habla TLS un cliente, algo más difícil de falsificar por descuido que cualquier cabecera y más fácil de falsificar a propósito de lo que admite la mayoría de los proveedores. Es una señal fuerte sobre la forma del software que hay al otro lado, una señal débil sobre la intención y ninguna señal sobre la identidad. Úsala para cazar la automatización que nunca intentó parecer humana, apílala con el origen de la IP y los marcadores headless para la que sí lo intentó, y no construyas una regla de bloqueo que se sostenga solo sobre ella.
FAQ