TLS-фингерпринтинг: как работают JA3 и JA4 и почему прокси их не меняет

TLS-отпечаток позволяет серверу понять, какая программа открыла HTTPS-сессию, — по одному лишь первому ходу. Ещё до начала шифрования клиент сообщает, что он умеет: версии протокола, списки шифров, номера расширений, предпочтительные группы для обмена ключами. Chrome, Firefox, curl и скрипт на Python делают это каждый по-своему, узнаваемо. JA3 сворачивает эти поля в MD5-хеш, а JA4 — его преемник, которому не мешает перемешивание расширений в браузерах. Обычный прокси лишь передаёт зашифрованный поток, поэтому сайт видит отпечаток вашего клиента, а не прокси.
Разберём, что содержит ClientHello, как считаются JA3 и JA4, почему перемешивание расширений «сломало» JA3 для Chrome, как сайты используют эти значения вместе с репутацией IP и что из этого следует для тех, кто работает с HTTP-клиентами через прокси.
Резидентные прокси
Резидентные IP с точной геолокацией для доступа к региональному контенту
Что выдаёт ClientHello
Любое TLS-соединение начинается с того, что клиент отправляет ClientHello открытым текстом (часть данных скрывает только более новый механизм Encrypted Client Hello). Его поля определяет TLS-библиотека и её настройки, а не пользователь:
- Версии протокола — например, TLS 1.2 в устаревшем поле и TLS 1.3 в расширении supported_versions.
- Наборы шифров — какие именно и в какой последовательности, зависит от криптобиблиотеки: в Chrome это BoringSSL, в Firefox — NSS, а Python и большинство консольных утилит опираются на OpenSSL.
- Расширения — имя сервера (SNI), ALPN, поддерживаемые группы, алгоритмы подписи, обмен ключами, сессионные билеты и другие.
- Группы и форматы точек — кривые для обмена ключами вроде X25519, на которые клиент согласен.
- Значения GREASE — случайные «заглушки» по RFC 8701, которые Chrome вставляет, чтобы серверы спокойно относились к неизвестным записям.
Два клиента, которые оба представляются свежим Chrome в User-Agent, но построены на разных библиотеках, отправляют заметно разные ClientHello. На этом разрыве и держится TLS-фингерпринтинг.
Как считается JA3
JA3 опубликовали в 2017 году трое инженеров Salesforce. Метод берёт пять полей ClientHello, записывает каждое десятичными числами через дефис, разделяет поля запятыми и хеширует результат MD5:
TLSVersion,Ciphers,Extensions,EllipticCurves,EllipticCurvePointFormats
Значения GREASE перед хешированием выбрасываются, чтобы случайные заглушки не меняли результат. Небольшой скрипт ниже показывает идею на вымышленных значениях:
import hashlib
GREASE_SET = {0x0a0a + 0x1010 * n for n in range(16)}
def build_ja3(version, cipher_ids, ext_ids, curve_ids, point_fmts):
def joined(values):
return "-".join(str(v) for v in values if v not in GREASE_SET)
raw_text = ",".join([
str(version),
joined(cipher_ids),
joined(ext_ids),
joined(curve_ids),
joined(point_fmts),
])
return raw_text, hashlib.md5(raw_text.encode()).hexdigest()
sample_hello = dict(
version=771,
cipher_ids=[0x2a2a, 4865, 4866, 4867, 49195, 49199],
ext_ids=[0x3a3a, 0, 23, 65281, 10, 11, 35, 16, 13, 51, 45, 43],
curve_ids=[29, 23, 24],
point_fmts=[0],
)
text_form, ja3_digest = build_ja3(**sample_hello)
print(text_form)
print(ja3_digest)Парный показатель JA3S снимает отпечаток ответа сервера (ServerHello). Вместе они помогают защитникам находить, например, вредоносные программы, которые связываются со своим управляющим сервером, — ради этого метод изначально и придумали.
Почему JA3 потерял точность: перемешивание расширений
JA3 учитывает расширения в том порядке, в котором их прислали. С выходом Chrome 110 в начале 2023 года браузеры на движке Chromium тасуют список расширений при каждом новом рукопожатии — чтобы серверы перестали опираться на одну неизменную раскладку. В итоге одна установка Chrome даёт множество разных хешей JA3: для опознания браузеров метод стал гораздо менее полезен, хотя для инструментов с фиксированным порядком — многих скриптов и библиотек — по-прежнему работает.
JA4 и семейство JA4+
В 2023 году Джон Олтхаус, один из авторов JA3, представил через свою компанию FoxIO метод JA4. В его основе два решения: списки упорядочиваются по номерам до хеширования, и перемешивание ничего не меняет, а первый сегмент остаётся понятным человеку. Значение выглядит как t13d1714h2_4f0c1a9d27be_93b2d6e1a0c4 (пример вымышленный), подчёркивания делят его на три сегмента:
| Часть | Что внутри | Пример расшифровки |
|---|---|---|
| a | Читаемый заголовок: буква транспорта, версия протокола, передаётся ли имя хоста, двузначные счётчики шифров и расширений, метка ALPN | В t13d1714h2: t — TCP, 13 — поколение протокола, d — указан домен, далее 17 наборов шифров, 14 расширений и h2 первым в ALPN |
| b | Укороченный до 12 знаков SHA-256 от идентификаторов шифров после сортировки | Одинаков при любом порядке, в котором клиент их перечислил |
| c | Укороченный SHA-256 от отсортированных номеров расширений вместе со списком алгоритмов подписи | Не сдвигается, когда браузер тасует расширения |
Начальный фрагмент записан открытым текстом, поэтому по логам сразу понятно, что клиент работает по TLS 1.3 поверх QUIC (q) или TCP (t) либо не отправляет SNI. Семейство JA4+ добавляет отпечатки ответа сервера (JA4S), заголовков HTTP-запроса (JA4H), сертификатов (JA4X), TCP-рукопожатия (JA4T) и другие. Сам JA4 опубликован под свободной лицензией, а остальные методы JA4+ — под собственной лицензией FoxIO, поэтому перед коммерческим использованием её стоит прочитать.

Другие слои: HTTP/2 и TCP
TLS редко проверяют в одиночку. Рядом обычно смотрят ещё два сигнала:
- Отпечаток HTTP/2. Значения SETTINGS, размер WINDOW_UPDATE, данные о приоритетах и порядок псевдозаголовков у браузеров и библиотек различаются. Метод, популяризированный Akamai, кодирует их в короткую строку.
- Отпечаток TCP/IP. Начальный размер окна, TTL и опции TCP выдают операционную систему. Если IP принадлежит прокси, эти значения описывают ОС прокси-сервера, а не вашу, — одна из причин, по которой сайты сравнивают слои, а не доверяют одному.
Эти слои — родственники браузерных сигналов вроде canvas и WebGL; о них подробно в материале о фингерпринтинге браузера.
Почему прокси не меняет TLS-отпечаток
Большинство прокси пропускают TLS, не вмешиваясь в него:
- HTTP-прокси с методом CONNECT открывает до сайта «сырой» TCP-туннель, а рукопожатие TLS через него выполняет ваш клиент.
- SOCKS5-прокси делает то же на более низком уровне — разница объяснена в статье SOCKS5 или HTTP.
В обоих случаях до сайта доходит тот ClientHello, который сформировала ваша программа. Сайт видит IP прокси вместе с TLS-отпечатком вашего клиента. Исключение — перехватывающий прокси, который завершает TLS у себя и открывает новое соединение: корпоративные шлюзы инспекции трафика или отладочные инструменты. Тогда сайт видит отпечаток программы прокси. Разница между туннелированием и перехватом разобрана в материале об SSL/HTTPS-прокси.

Как сайты используют TLS-отпечатки
Системы защиты от ботов и CDN, включая Bot Management от Cloudflare, передают значения JA3 и JA4 в свои правила и модели. Типичные сценарии:
- Проверка согласованности. Запрос, который в User-Agent называет себя Chrome, а приходит с отпечатком Python-библиотеки или curl, противоречив, и это расхождение весит больше, чем каждое значение по отдельности.
- Каталоги известных инструментов. Отпечатки популярных HTTP-библиотек, сканеров и семейств вредоносного ПО собраны в базы и получают оценку риска.
- Белые списки. Партнёров и сервисы мониторинга с известным отпечатком можно пропускать мимо лимитов.
- Кластеризация. Множество IP с одним редким отпечатком и одинаковым поведением указывают на одного оператора — поэтому одна лишь ротация адресов автоматизацию не скрывает.
Полная картина уровней защиты, от репутации IP до поведения, — в обзоре о том, как сайты распознают ботов.
Что это значит для автоматизации через прокси
TLS-отпечатки — ещё один довод в пользу того, что ответственный сбор данных начинается с разрешения, а не с маскировки:
- Сначала официальные API и выгрузки. Они рассчитаны на программных клиентов, и отпечатки там роли не играют.
- Уважайте блокировки и проверки. Если защита сайта останавливает ваш клиент, это сигнал снизить темп, запросить доступ или взять другой источник. О темпе, кешировании и других вежливых практиках — в статье о том, как снизить риск блокировок при парсинге.
- Свои сервисы тестируйте настоящими браузерами. Для мониторинга и QA собственных сайтов фреймворки, управляющие полноценным браузером, дают подлинное браузерное рукопожатие. Существуют и библиотеки, воспроизводящие рукопожатие браузеров, их применяют в тестировании, но использование их для обхода защиты чужого сайта может нарушать его условия.
- Прокси — для маршрута и локации. Прокси определяет, откуда выходит трафик, что важно для геозависимого контента; выдавать себя за другой клиент он не должен и не умеет. Наши резидентные прокси созданы для доступа с точной геолокацией, а не для подмены программы, которой вы пользуетесь.
Как посмотреть собственный отпечаток
- Wireshark. Запишите трафик, отфильтруйте по
tls.handshake.type == 1и откройте ClientHello. Свежие версии показывают значения JA3 и JA4 в деталях рукопожатия. - Тестовые страницы-эхо. Некоторые публичные страницы просто показывают посетителю хеши его рукопожатия и параметры HTTP/2. Загрузите такую страницу один раз обычным браузером, второй — своей программой и положите результаты рядом.
- Журналы на своей инфраструктуре. Пограничные серверы и сети доставки контента способны записывать JA3 или JA4 для каждого запроса, и по ним видно, какие клиентские стеки заходят на ваш сайт.

Частые вопросы о TLS-фингерпринтинге
Что такое отпечаток JA3?
JA3 — это 32-символьная MD5-строка, собранная из пяти значений рукопожатия: версии протокола, шифров, номеров расширений, групп и форматов точек. По ней узнают программный стек и его настройки, но не отдельного пользователя.
Чем JA3 отличается от JA4?
JA4 упорядочивает шифры и расширения до хеширования, так что значение остаётся прежним у браузеров, тасующих расширения, а начинается оно с фрагмента, понятного без расшифровки. У FoxIO есть и родственные методы — для HTTP-заголовков, ответов сервера, сертификатов и TCP.
Меняет ли прокси или VPN TLS-отпечаток?
Туннелирующие прокси и VPN — нет: они меняют IP, а рукопожатие формирует ваша программа. Собственный отпечаток показывают только перехватывающие прокси, которые завершают TLS у себя.
Могут ли сайты блокировать по TLS-отпечатку?
Да, многие системы защиты от ботов используют JA3 или JA4 как один из сигналов, особенно если он противоречит User-Agent. Обычно его сочетают с репутацией IP, данными HTTP/2 и поведением.
Законен ли TLS-фингерпринтинг?
Метод анализирует технические параметры, которые клиент открыто отправляет при рукопожатии, и широко применяется для безопасности и борьбы с мошенничеством. Законность конкретного применения зависит от местных правил о персональных данных и от того, с какой информацией эти данные сопоставляют.


