Saltar al contenido principal
en/blog/obscura/research/tls-fingerprinting/

obscura/research/tls-fingerprinting

2 min read

Overview

TLS fingerprinting identifies clients by the parameters they send during the TLS handshake (ClientHello message). Different browsers and operating systems use different TLS configurations.

JA3 Fingerprint

JA3 is a hash computed from the TLS ClientHello:

JA3 = MD5(Ciphers + Extensions + EllipticCurves + EllipticCurvePointFormats)

Where each field is concatenated:

ciphers: 49199,49196,52393,...  (list of cipher suite IDs)
extensions: 0,23,65281,...       (list of extension type IDs)
curves: 29,23,24,...             (list of supported groups)
formats: 0                       (EC point formats)

Example JA3 Hashes

Browser JA3
Chrome 120 (Windows 11) 6734f37431670b3ab4292b8f60f29984
Firefox 121 (Windows 11) d1b8d7e1c7c8b0a6b1a2c3d4e5f6a7b8
Safari 17 (macOS 14) 9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d
Chrome 120 (Android 14) b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6

JA4 Fingerprint (Next Generation)

JA4 extends JA3 by also analyzing:

  • TLS version
  • SNI presence
  • ALPN protocols
  • HTTP/2 settings

Format: tls_version.ciphers.extensions.sni.alpn

HTTP/2 Fingerprinting

HTTP/2 connections reveal additional fingerprints via:

  • SETTINGS frame parameters (MAX_CONCURRENT_STREAMS, INITIAL_WINDOW_SIZE, etc.)
  • WINDOW_UPDATE timing
  • PING frame behavior
  • Priority frame structure

Spoofing TLS Fingerprint

Tools like TLSMask and utls can modify the ClientHello to mimic another browser:

Actual ClientHello  [TLS Spoofer]  Mimicked ClientHello  Server

Approach

  1. Capture a real ClientHello from the target browser/OS
  2. Store as a template
  3. Modify outbound ClientHello to match the template parameters
  4. Forward to destination

Implications for Obscura:

  • TLS spoofing can be done at the proxy level, unlike Canvas/WebGL/audio
  • Go has utls library (fork of crypto/tls with ClientHello customization)
  • Rust has tls-parser + custom TLS implementation
  • The proxy must terminate TLS anyway for MITM, so the TLS fingerprint seen by the server will be the proxy's Go/Rust TLS implementation unless consciously spoofed

Conclusions

  • TLS fingerprinting (JA3/JA4) is tractable at the proxy level
  • Go's utls library provides direct ClientHello manipulation
  • Must be a core feature of Obscura
  • Without TLS spoofing, the proxy's own TLS library would leak that a proxy is in use