Tu scraper envía cabeceras de Chrome perfectas, se ejecuta detrás de una IP residencial limpia, y aun así obtiene un 403 en la primerísima petición. Sin captcha, sin página de desafío, nada que resolver. El sitio te identificó antes de que se intercambiara un solo byte de HTTP — durante el handshake TLS.
Este artículo explica cómo funcionan realmente las huellas JA3 y JA4, por qué son el caballo de batalla silencioso de todos los grandes sistemas antibot en 2026, y cómo ver tu propia huella en diez segundos. Si quieres primero las herramientas de evasión, lo cubrimos en Evade el fingerprinting TLS con curl_cffi & tls-client — esta es la pieza complementaria sobre cómo funciona el lado de la detección.
Antes de la teoría, mira tu propio handshake. Abre nuestro verificador gratuito de JA3/JA4 — te devuelve la huella TLS que tu cliente acaba de presentar y te dice con qué coincide:
# From a terminal - see what curl's TLS looks like:
curl https://www.jibaoproxy.com/tools/fingerprint.html
# Then open the same URL in Chrome and compare.
Ejecuta ambos y verás el sentido de todo este artículo: curl y Chrome producen huellas completamente distintas, sin importar qué cabecera User-Agent configures.
Toda conexión HTTPS comienza con un mensaje ClientHello, enviado en texto plano antes de que empiece cualquier cifrado. En él, tu cliente anuncia:
Aquí está la clave de la detección: estas listas y su orden exacto están grabadas en la librería TLS contra la que se compiló tu cliente. El BoringSSL de Chrome anuncia una combinación específica. El OpenSSL de Python anuncia una distinta. El crypto/tls de Go una tercera. No puedes cambiar esto con cabeceras — se negocia por debajo de la capa HTTP, por la propia librería.
JA3 (Salesforce, 2017) concatena cinco campos del ClientHello — versión de TLS, cifrados, extensiones, curvas, formatos de punto — en una cadena y le aplica un hash MD5:
771,4865-4866-4867-49195-49199,0-23-65281-10-11-35-16,29-23-24,0
|
v MD5
cd08e31494f9531f560d64c695473da9
Un hash por stack de TLS. Cada copia de Chrome 137 en Windows produce (casi) el mismo JA3; cada python-requests sobre OpenSSL 3.x produce el mismo JA3 distinto. Los defensores mantienen tablas de búsqueda: hash X = Chrome, hash Y = requests, hash Z = bot de Go. Si tu User-Agent dice Chrome pero tu JA3 dice OpenSSL, te bloquean — al instante, en silencio, de forma barata.
JA3 tenía problemas: Chrome empezó a aleatorizar el orden de las extensiones en 2023 (rompiendo el JA3 ingenuo), y MD5 es poco estructurado — un hash no te dice nada sobre por qué difieren dos clientes. JA4 (FoxIO, 2023) corrigió ambas cosas y es lo que ejecutan hoy los proveedores serios:
JA4 = t13d1516h2_8daaf6152771_b0da82dd1658
| | |
a: protocol b: ciphers c: extensions
(TLS 1.3, 16 ciphers, (sorted, truncated
h2 ALPN, domain SNI) SHA256)
Todos los sistemas que importan: Cloudflare expone JA3/JA4 directamente en sus reglas de gestión de bots; DataDome y PerimeterX lo incorporan a su puntuación a nivel de red (consulta nuestra guía de DataDome/PerimeterX); Akamai lleva ejecutando fingerprinting TLS más tiempo que nadie. Es popular porque es gratis de calcular, imposible de falsificar desde la capa HTTP y atrapa al 90% de la automatización ingenua — cada script de requests/httpx/axios/Go-http jamás escrito — antes de que necesite ejecutarse cualquier JavaScript.
Esto sorprende a la gente: un proxy cambia tu IP, pero tu handshake TLS pasa sin cambios. El túnel CONNECT (o el flujo SOCKS5) transporta los bytes de tu ClientHello textualmente hasta el objetivo. IP residencial + JA3 de librería requests = "un bot ejecutándose en una IP residencial". Mejor que una IP de centro de datos, pero sigue siendo un bot.
La IP y la huella TLS son señales independientes y necesitas ambas limpias:
| IP | Huella TLS | Veredicto en 2026 |
|---|---|---|
| Centro de datos | Librería (requests/Go) | Bloqueado en todas partes donde importe |
| Residencial | Librería | Bloqueado en sitios que verifican JA4 |
| Centro de datos | Suplantación de navegador | Bloqueado por reputación de IP |
| Residencial | Suplantación de navegador | Pasa las verificaciones a nivel de red |
Dos caminos, según las herramientas:
Clientes HTTP — usa una librería de suplantación que reimplemente el ClientHello exacto de un navegador: curl_cffi (Python), tls-client (Python/Go), got-scraping (Node). Código funcional completo en la guía de curl_cffi:
from curl_cffi import requests
r = requests.get(
"https://target.example",
impersonate="chrome",
proxies={"https": "socks5h://USERNAME:[email protected]:913"},
)
Navegadores reales (Playwright, agentes con navegador, navegadores antidetección) — nada que hacer en la capa TLS; la huella es genuinamente la de Chrome. Tu riesgo vive en otra parte: reputación de IP y detección de CDP.
Luego verifica, no asumas. Las versiones se desactualizan — una librería de suplantación fijada al handshake de Chrome 120 se lee como "navegador sospechosamente desactualizado" en 2026. Vuelve a probar después de cada actualización de dependencias:
Combina tu TLS suplantado con IP residenciales — 500MB de tráfico gratis, sin tarjeta.
Comenzar prueba gratuitaLos nuevos usuarios reciben 500MB al registrarse, más un bono en la primera recarga. Oferta por tiempo limitado.