Votre scraper envoie des en-têtes Chrome parfaits, tourne derrière une IP résidentielle propre, et reçoit quand même un 403 dès la toute première requête. Pas de captcha, pas de page de défi, rien à résoudre. Le site vous a identifié avant qu'un seul octet de HTTP ne soit échangé — pendant le handshake TLS.
Cet article explique comment fonctionnent réellement les empreintes JA3 et JA4, pourquoi elles sont le cheval de bataille silencieux de tous les grands systèmes anti-bot en 2026, et comment voir votre propre empreinte en dix secondes. Si vous voulez d'abord les outils de contournement, nous les avons couverts dans Contourner le fingerprinting TLS avec curl_cffi & tls-client — ceci est l'article complémentaire sur le fonctionnement du côté détection.
Avant la théorie, regardez votre propre handshake. Ouvrez notre vérificateur gratuit JA3/JA4 — il vous renvoie l'empreinte TLS que votre client vient de présenter et vous dit à quoi elle correspond :
# 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.
Lancez les deux et vous verrez tout l'intérêt de cet article : curl et Chrome produisent des empreintes complètement différentes, quel que soit l'en-tête User-Agent que vous configurez.
Toute connexion HTTPS commence par un message ClientHello, envoyé en clair avant que le moindre chiffrement ne débute. Dans ce message, votre client annonce :
Voici la clé de la détection : ces listes et leur ordre exact sont gravés dans la bibliothèque TLS avec laquelle votre client a été compilé. Le BoringSSL de Chrome annonce une combinaison spécifique. L'OpenSSL de Python en annonce une différente. Le crypto/tls de Go une troisième. Vous ne pouvez pas changer cela avec des en-têtes — c'est négocié sous la couche HTTP, par la bibliothèque elle-même.
JA3 (Salesforce, 2017) concatène cinq champs du ClientHello — version de TLS, chiffrements, extensions, courbes, formats de point — en une chaîne et lui applique 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 par stack TLS. Chaque copie de Chrome 137 sous Windows produit (presque) le même JA3 ; chaque python-requests sur OpenSSL 3.x produit le même JA3 distinct. Les défenseurs maintiennent des tables de correspondance : hash X = Chrome, hash Y = requests, hash Z = bot Go. Si votre User-Agent dit Chrome mais que votre JA3 dit OpenSSL, vous êtes bloqué — instantanément, en silence, à moindre coût.
JA3 avait des problèmes : Chrome a commencé à randomiser l'ordre des extensions en 2023 (cassant le JA3 naïf), et MD5 est peu structuré — un hash ne vous dit rien sur pourquoi deux clients diffèrent. JA4 (FoxIO, 2023) a corrigé les deux et c'est ce qu'exécutent aujourd'hui les fournisseurs sérieux :
JA4 = t13d1516h2_8daaf6152771_b0da82dd1658
| | |
a: protocol b: ciphers c: extensions
(TLS 1.3, 16 ciphers, (sorted, truncated
h2 ALPN, domain SNI) SHA256)
Tous les systèmes qui comptent : Cloudflare expose JA3/JA4 directement dans ses règles de gestion des bots ; DataDome et PerimeterX l'intègrent à leur scoring au niveau réseau (voir notre guide DataDome/PerimeterX) ; Akamai pratique le fingerprinting TLS depuis plus longtemps que quiconque. C'est populaire parce que c'est gratuit à calculer, impossible à falsifier depuis la couche HTTP et que cela attrape 90 % de l'automatisation naïve — chaque script requests/httpx/axios/Go-http jamais écrit — avant que le moindre JavaScript ne doive s'exécuter.
Cela surprend les gens : un proxy change votre IP, mais votre handshake TLS passe sans modification. Le tunnel CONNECT (ou le flux SOCKS5) transporte les octets de votre ClientHello tels quels jusqu'à la cible. IP résidentielle + JA3 de la bibliothèque requests = "un bot tournant sur une IP résidentielle". Mieux qu'une IP de centre de données, mais cela reste un bot.
L'IP et l'empreinte TLS sont des signaux indépendants et vous avez besoin que les deux soient propres :
| IP | Empreinte TLS | Verdict en 2026 |
|---|---|---|
| Centre de données | Bibliothèque (requests/Go) | Bloqué partout où cela compte |
| Résidentielle | Bibliothèque | Bloqué sur les sites qui vérifient JA4 |
| Centre de données | Impersonation de navigateur | Bloqué pour réputation d'IP |
| Résidentielle | Impersonation de navigateur | Passe les vérifications au niveau réseau |
Deux chemins, selon les outils :
Clients HTTP — utilisez une bibliothèque d'impersonation qui réimplémente le ClientHello exact d'un navigateur : curl_cffi (Python), tls-client (Python/Go), got-scraping (Node). Code fonctionnel complet dans le guide curl_cffi :
from curl_cffi import requests
r = requests.get(
"https://target.example",
impersonate="chrome",
proxies={"https": "socks5h://USERNAME:[email protected]:913"},
)
Vrais navigateurs (Playwright, agents avec navigateur, navigateurs anti-détection) — rien à faire au niveau TLS ; l'empreinte est authentiquement celle de Chrome. Votre risque se situe ailleurs : réputation d'IP et détection de CDP.
Ensuite vérifiez, ne présumez pas. Les versions se périment — une bibliothèque d'impersonation figée sur le handshake de Chrome 120 se lit comme "navigateur suspectement obsolète" en 2026. Retestez après chaque mise à jour de dépendances :
Associez votre TLS impersoné à des IP résidentielles — 500 Mo de trafic gratuit, sans carte.
Démarrer l'essai gratuitLes nouveaux utilisateurs reçoivent 500 Mo à l'inscription, plus un bonus sur la première recharge. Offre à durée limitée.