TLS-фінгерпринтинг і хеші JA4: пояснення
Чому повідомлення TLS Client Hello — золота жила для ідентифікації пристроїв і як хеші JA4 дають стабільний фінгерпринт, що переживає оновлення браузера.
Кожне HTTPS-з'єднання починається з TLS-рукостискання, а кожне TLS-рукостискання починається з повідомлення Client Hello. Це повідомлення містить масу інформації про клієнта, що підключається, — набори шифрів, розширення, підтримувані криві, алгоритми підпису, — яка суттєво різниться між браузерами, версіями та операційними системами. TLS-фінгерпринтинг фіксує цю інформацію та використовує її як сигнал ідентифікації.
Що міститься в Client Hello?
Коли браузер підключається до HTTPS-сервера, він надсилає повідомлення Client Hello, що містить: підтримувану версію TLS, список наборів шифрів, які він готовий використовувати, TLS-розширення, які він включає (як-от SNI, ALPN і key share), підтримувані еліптичні криві, прийнятні алгоритми підпису та методи стиснення, які він пропонує.
Кожне сімейство браузерів має характерний фінгерпринт. Chrome, Firefox і Safari надсилають різне впорядкування наборів шифрів, різні набори розширень і різні переваги щодо кривих. Навіть у межах одного сімейства браузерів різні версії можуть надсилати трохи різні повідомлення Client Hello у міру додавання чи виведення з обігу наборів шифрів.
Від JA3 до JA4
JA3 був першим хешем TLS-фінгерпринтингу, представленим Salesforce у 2017 році. Він об'єднує версію TLS, набори шифрів, розширення, еліптичні криві та формати точок EC у рядок і обчислює MD5-хеш. Хоч це й був прорив, JA3 має обмеження: він видає єдиний непрозорий хеш, який важко аналізувати, а незначні зміни в будь-якому полі дають зовсім інший хеш.
JA4, представлений FoxIO у 2023 році, покращує JA3 у кількох аспектах. Він видає структурований фінгерпринт із трьох компонентів: читабельний префікс (як-от «t13d1715h2» — TLS 1.3, 17 наборів шифрів, 15 розширень, HTTP/2), впорядкований хеш наборів шифрів і впорядкований хеш розширень. Ця структура робить фінгерпринти JA4 придатними для аналізу з першого погляду, зберігаючи при цьому точність, потрібну для ідентифікації.
Чому TLS-фінгерпринти важливі для device intelligence
TLS-фінгерпринти цінні тим, що збираються до виконання будь-якого JavaScript. Бот, який підробляє свій user agent, фальсифікує рендеринг canvas і латає властивості navigator, усе одно надсилає справжнє повідомлення Client Hello від тієї TLS-бібліотеки, яку насправді використовує. Якщо Client Hello каже «бібліотека crypto/tls мови Go», а user agent каже «Chrome 124», ми знаємо, що щось підроблено.
Ця перехресна перевірка надзвичайно потужна для виявлення ботів. Більшість фреймворків автоматизації — Selenium, Puppeteer, Playwright — використовують нативний TLS-стек браузера, тож їхні TLS-фінгерпринти збігаються з браузером, яким вони керують. Але кастомні HTTP-клієнти, скрапери на основі Go та Python-скрипти, що використовують бібліотеку requests, мають характерні TLS-фінгерпринти, які одразу ідентифікують їх як небраузерні клієнти.
Стабільність TLS-фінгерпринта
Одна з проблем TLS-фінгерпринтингу — стабільність між оновленнями браузера. Коли Chrome додає чи видаляє набір шифрів, TLS-фінгерпринт змінюється. На практиці це трапляється рідше, ніж можна було б очікувати. Список наборів шифрів Chrome відносно стабільний — суттєві зміни відбуваються раз чи двічі на рік, а не з кожною версією.
Структурований формат JA4 тут допомагає. Читабельний префікс лишається стабільним між мінорними змінами версій (кількість наборів шифрів і розширень змінюється нечасто), тож навіть коли детальний хеш змінюється, префікс забезпечує тяглість. У нашій багаторівневій системі ідентифікації дані TLS-фінгерпринта розміщено в Tier 2 — достатньо стабільні, щоб робити внесок в ідентифікацію, але обробляються через міжсесійне зіставлення, аби враховувати очікуваний дрейф.
Збір на боці сервера
На відміну від клієнтських сигналів, які потребують виконання JavaScript, TLS-фінгерпринти збираються повністю на боці сервера. Наші edge-сервери інспектують сире TLS-рукостискання та витягують Client Hello до встановлення з'єднання. Це означає, що TLS-фінгерпринтинг працює навіть тоді, коли JavaScript заблоковано, коли в браузері встановлено розширення для приватності або коли клієнт узагалі не є браузером.
Ця серверна природа також робить TLS-фінгерпринти стійкими до підробки. Хоча теоретично можливо сформувати кастомне TLS Client Hello, що імітує конкретний браузер, для цього потрібно реалізувати TLS на низькому рівні — набагато більше зусиль, ніж зміна рядка user agent. Більшість інструментів підробки навіть не намагаються цього робити.
Інтеграція з ідентифікацією пристрою
У нашому рушії ідентифікації пристроїв TLS-фінгерпринт слугує водночас сигналом і валідатором. Як сигнал він робить внесок у загальний фінгерпринт пристрою з власною вагою ідентифікації. Як валідатор він забезпечує перехресну перевірку заявленої ідентичності браузера. Якщо JavaScript-сигнали кажуть «Chrome на macOS», а TLS-фінгерпринт каже «Firefox на Linux», ця розбіжність вмикає прапорець втручання в нашому аналізі Smart Signals.