Fingerprinting TLS i hashe JA4 — jak to działa
Dlaczego wiadomości TLS Client Hello to kopalnia wiedzy do identyfikacji urządzeń — i jak hashe JA4 dają stabilny fingerprint, który przetrwa aktualizacje przeglądarki.
Każde połączenie HTTPS zaczyna się od handshake'u TLS, a każdy handshake TLS zaczyna się od wiadomości Client Hello. Ta wiadomość zawiera mnóstwo informacji o łączącym się kliencie — zestawy szyfrów, rozszerzenia, obsługiwane krzywe, algorytmy podpisu — które znacznie różnią się między przeglądarkami, wersjami i systemami operacyjnymi. Fingerprinting TLS przechwytuje te informacje i wykorzystuje je jako sygnał identyfikacyjny.
Co znajduje się w Client Hello?
Gdy przeglądarka łączy się z serwerem HTTPS, wysyła wiadomość Client Hello zawierającą: obsługiwaną wersję TLS, listę zestawów szyfrów, których jest gotowa użyć, rozszerzenia TLS, które dołącza (takie jak SNI, ALPN i key share), obsługiwane krzywe eliptyczne, akceptowane algorytmy podpisu oraz oferowane metody kompresji.
Każda rodzina przeglądarek ma charakterystyczny fingerprint. Chrome, Firefox i Safari wysyłają różne uporządkowania zestawów szyfrów, różne zestawy rozszerzeń i różne preferencje krzywych. Nawet w obrębie tej samej rodziny przeglądarek różne wersje mogą wysyłać nieco odmienne wiadomości Client Hello w miarę dodawania lub wycofywania zestawów szyfrów.
Od JA3 do JA4
JA3 był pierwszym hashem do fingerprintingu TLS, wprowadzonym przez Salesforce w 2017 roku. Łączy wersję TLS, zestawy szyfrów, rozszerzenia, krzywe eliptyczne i formaty punktów EC w jeden ciąg znaków i oblicza hash MD5. Choć przełomowy, JA3 ma ograniczenia: produkuje pojedynczy, nieprzejrzysty hash, który trudno analizować, a drobne zmiany w dowolnym polu dają zupełnie inny hash.
JA4, wprowadzony przez FoxIO w 2023 roku, ulepsza JA3 na kilka sposobów. Produkuje ustrukturyzowany fingerprint składający się z trzech elementów: czytelnego dla człowieka prefiksu (jak "t13d1715h2" — TLS 1.3, 17 zestawów szyfrów, 15 rozszerzeń, HTTP/2), uporządkowanego hasha zestawów szyfrów oraz uporządkowanego hasha rozszerzeń. Ta struktura sprawia, że fingerprinty JA4 można analizować na pierwszy rzut oka, zachowując jednocześnie precyzję potrzebną do identyfikacji.
Dlaczego fingerprinty TLS mają znaczenie dla device intelligence
Fingerprinty TLS są cenne, ponieważ zbierane są przed wykonaniem jakiegokolwiek kodu JavaScript. Bot, który podszywa się pod cudzy user agent, fałszuje renderowanie canvas i łata właściwości obiektu navigator, wciąż wysyła autentyczną wiadomość Client Hello z tej biblioteki TLS, której faktycznie używa. Jeśli Client Hello mówi "biblioteka crypto/tls języka Go", a user agent mówi "Chrome 124", wiemy, że coś jest podrabiane.
Ta wzajemna weryfikacja jest niezwykle skuteczna w wykrywaniu botów. Większość frameworków do automatyzacji — Selenium, Puppeteer, Playwright — korzysta z natywnego stosu TLS przeglądarki, więc ich fingerprinty TLS pasują do przeglądarki, którą sterują. Ale własne klienty HTTP, scrapery oparte na języku Go oraz skrypty w Pythonie korzystające z biblioteki requests mają charakterystyczne fingerprinty TLS, które natychmiast identyfikują je jako klientów niebędących przeglądarką.
Stabilność fingerprintu TLS
Jednym z problemów przy fingerprintingu TLS jest stabilność między aktualizacjami przeglądarki. Gdy Chrome dodaje lub usuwa zestaw szyfrów, fingerprint TLS się zmienia. W praktyce dzieje się to rzadziej, niż można by oczekiwać. Lista zestawów szyfrów w Chrome jest względnie stabilna — istotne zmiany zdarzają się raz lub dwa razy w roku, a nie przy każdej wersji.
Ustrukturyzowany format JA4 pomaga w tym zakresie. Czytelny dla człowieka prefiks pozostaje stabilny między drobnymi zmianami wersji (liczba zestawów szyfrów i rozszerzeń nie zmienia się często), więc nawet gdy zmienia się szczegółowy hash, prefiks zapewnia ciągłość. W naszym wielowarstwowym systemie identyfikacji dane fingerprintu TLS umieszczane są w warstwie Tier 2 — wystarczająco stabilne, by przyczyniać się do identyfikacji, ale przetwarzane przez dopasowywanie międzysesyjne w celu obsługi spodziewanych odchyleń.
Zbieranie po stronie serwera
W przeciwieństwie do sygnałów po stronie klienta, które wymagają wykonania kodu JavaScript, fingerprinty TLS zbierane są w całości po stronie serwera. Nasze serwery brzegowe analizują surowy handshake TLS i wyodrębniają Client Hello, zanim połączenie zostanie nawiązane. Oznacza to, że fingerprinting TLS działa nawet wtedy, gdy JavaScript jest zablokowany, gdy w przeglądarce zainstalowane są rozszerzenia chroniące prywatność lub gdy klient w ogóle nie jest przeglądarką.
Ta serwerowa natura sprawia również, że fingerprinty TLS są odporne na podszywanie się. Choć teoretycznie możliwe jest spreparowanie własnej wiadomości TLS Client Hello naśladującej konkretną przeglądarkę, wymaga to implementacji TLS na niskim poziomie — znacznie więcej wysiłku niż zmiana ciągu user agent. Większość narzędzi do podszywania się nawet tego nie próbuje.
Integracja z identyfikacją urządzeń
W naszym silniku identyfikacji urządzeń fingerprint TLS pełni rolę zarówno sygnału, jak i walidatora. Jako sygnał przyczynia się do ogólnego fingerprintu urządzenia z własną wagą identyfikacyjną. Jako walidator zapewnia weryfikację krzyżową względem deklarowanej tożsamości przeglądarki. Jeśli sygnały JavaScript mówią "Chrome na macOS", a fingerprint TLS mówi "Firefox na Linuksie", rozbieżność uruchamia flagę manipulacji w naszej analizie Smart Signals.