TLS Fingerprinting and JA4 Hashes Explained
Every HTTPS connection begins with a TLS handshake, and every TLS handshake begins with a Client Hello message. This message contains a wealth of information about the connecting client — cipher suites, extensions, supported curves, signature algorithms — that varies significantly across browsers, versions, and operating systems. TLS fingerprinting captures this information and uses it as an identification signal.
What Is in a Client Hello?
When a browser connects to an HTTPS server, it sends a Client Hello message containing: the TLS version it supports, the list of cipher suites it is willing to use, the TLS extensions it includes (like SNI, ALPN, and key share), the elliptic curves it supports, the signature algorithms it accepts, and the compression methods it offers.
Each browser family has a distinctive fingerprint. Chrome, Firefox, and Safari all send different cipher suite orderings, different extension sets, and different curve preferences. Even within the same browser family, different versions may send slightly different Client Hello messages as cipher suites are added or deprecated.
From JA3 to JA4
JA3 was the original TLS fingerprinting hash, introduced by Salesforce in 2017. It concatenates the TLS version, cipher suites, extensions, elliptic curves, and EC point formats into a string and computes an MD5 hash. While groundbreaking, JA3 has limitations: it produces a single opaque hash that is difficult to analyze, and minor changes in any field produce a completely different hash.
JA4, introduced by FoxIO in 2023, improves on JA3 in several ways. It produces a structured fingerprint with three components: a human-readable prefix (like "t13d1715h2" — TLS 1.3, 17 cipher suites, 15 extensions, HTTP/2), an ordered hash of the cipher suites, and an ordered hash of the extensions. This structure makes JA4 fingerprints analyzable at a glance while maintaining the precision needed for identification.
Why TLS Fingerprints Matter for Device Intelligence
TLS fingerprints are valuable because they are collected before any JavaScript executes. A bot that spoofs its user agent, fakes its canvas rendering, and patches its navigator properties still sends a genuine Client Hello message from whatever TLS library it actually uses. If the Client Hello says "Go's crypto/tls library" but the user agent says "Chrome 124," we know something is being spoofed.
This cross-validation is extremely powerful for bot detection. Most automation frameworks — Selenium, Puppeteer, Playwright — use the browser's native TLS stack, so their TLS fingerprints match the browser they control. But custom HTTP clients, Go-based scrapers, and Python scripts using the requests library all have distinctive TLS fingerprints that immediately identify them as non-browser clients.
TLS Fingerprint Stability
One concern with TLS fingerprinting is stability across browser updates. When Chrome adds or removes a cipher suite, the TLS fingerprint changes. In practice, this happens less frequently than you might expect. Chrome's cipher suite list is relatively stable — major changes happen once or twice a year, not with every version.
JA4's structured format helps here. The human-readable prefix remains stable across minor version changes (the count of cipher suites and extensions does not change often), so even when the detailed hash changes, the prefix provides continuity. In our multi-tier identification system, TLS fingerprint data is placed in Tier 2 — stable enough to contribute to identification, but processed through cross-session matching to handle expected drift.
Server-Side Collection
Unlike client-side signals that require JavaScript execution, TLS fingerprints are collected entirely server-side. Our edge servers inspect the raw TLS handshake and extract the Client Hello before the connection is established. This means TLS fingerprinting works even when JavaScript is blocked, when the browser has privacy extensions installed, or when the client is not a browser at all.
This server-side nature also makes TLS fingerprints resistant to spoofing. While it is theoretically possible to craft a custom TLS Client Hello that mimics a specific browser, doing so requires implementing TLS at a low level — far more effort than changing a user agent string. Most spoofing tools do not attempt it.
Integration with Device Identification
In our device identification engine, the TLS fingerprint serves as both a signal and a validator. As a signal, it contributes to the overall device fingerprint with its own identification weight. As a validator, it provides a cross-check against the claimed browser identity. If the JavaScript signals say "Chrome on macOS" but the TLS fingerprint says "Firefox on Linux," the discrepancy triggers a tampering flag in our Smart Signals analysis.