TLS Fingerprinting: How JA3 and JA4 Identify You Before You Send a Byte

Encryption hides the contents of your HTTPS connection — but the negotiation that sets up that encryption happens in the clear. The very first message your client sends, before a single byte of application data, has a distinctive shape. JA3 and JA4 turn that shape into a fingerprint that can identify your software, and sometimes route, throttle, or block you on the spot.

Every HTTPS connection starts with a TLS handshake, and the handshake starts with a message called the ClientHello. It is sent unencrypted, because the two sides have not yet agreed on a key. Inside it, your client announces everything it is willing to do: which TLS versions it supports, which cipher suites it prefers and in what order, which extensions it understands, which elliptic curves and signature algorithms it offers.

None of that is secret. None of it has to be. But taken together, the exact set and ordering of those parameters is remarkably specific to a particular piece of software at a particular version. Chrome 124 produces a different ClientHello from Firefox, which produces a different one from Python’s requests library, which differs from Go’s standard library, which differs from a curl built against a specific OpenSSL version. TLS fingerprinting is the practice of hashing that ClientHello into a short, stable identifier and looking it up.

What Goes Into the Fingerprint

The original technique, JA3, was published by three engineers at Salesforce in 2017 — John Althouse, Jeff Atkinson, and Josh Atkins, whose initials gave it the name. JA3 builds a string from five fields of the ClientHello, in order:

  • The TLS version offered
  • The list of cipher suites
  • The list of extensions
  • The list of supported elliptic curves (named groups)
  • The list of elliptic-curve point formats

Each field is rendered as its numeric values joined by hyphens, the fields are joined by commas, and the whole string is hashed with MD5 to produce a 32-character fingerprint. A companion technique, JA3S, does the same for the server’s ServerHello, so you can fingerprint both ends of a conversation. Pairing a client JA3 with a server JA3S is a common way to identify specific malware command-and-control channels, because the malware and its server both produce consistent, unusual hashes.

Why ordering matters: Two clients can support the exact same cipher suites and still fingerprint differently, because they offer them in a different preference order. That ordering is baked into the TLS library and rarely changes between builds — which is exactly what makes it a stable signal.

Why JA3 Started to Break

JA3 worked well for years, but two developments eroded it. The first was GREASE (RFC 8701), a mechanism Google introduced to keep the TLS ecosystem flexible. GREASE makes clients insert random reserved values into their cipher and extension lists, so that middleboxes don’t hard-code assumptions about what they see. The side effect is that a naive JA3 implementation produces a different hash on every connection unless it explicitly strips the GREASE values out.

The second was TLS 1.3 and the rise of extension shuffling. Chrome began randomizing the order of some ClientHello extensions on each connection specifically to discourage fingerprinting and ossification. Against a technique that depends on extension ordering, that is fatal: the same browser now yields many different JA3 hashes.

JA4: The Redesign

In 2023, John Althouse — one of the original JA3 authors, now at FoxIO — released JA4, the centerpiece of a broader suite called JA4+ that fingerprints not just TLS but HTTP, TCP, SSH, and more. JA4 was designed to survive the things that broke JA3.

The biggest structural change is that JA4 is partly human-readable. Instead of one opaque MD5, a JA4 fingerprint is divided into sections you can read at a glance:

  • A prefix describing the transport and TLS version, whether SNI is present, the count of cipher suites, the count of extensions, and the first ALPN value — for example, whether the client is speaking HTTP/2 or HTTP/1.1
  • A truncated hash of the cipher suites, sorted numerically so that order-shuffling no longer changes the result
  • A truncated hash of the extensions and signature algorithms, also handled so that cosmetic reordering doesn’t matter

GREASE values are stripped by definition. Because the cipher and extension lists are sorted before hashing, Chrome’s randomization no longer produces a moving target. The result is a fingerprint that is both more stable than JA3 and more informative, because a human analyst can read meaningful structure out of the prefix without consulting a lookup table.

Property JA3 (2017) JA4 (2023)
Output Single MD5 hash Structured, partly human-readable
Handles GREASE Only if implementation strips it Yes, by design
Survives extension shuffling No — order-dependent Yes — lists are sorted
Scope TLS ClientHello / ServerHello TLS, HTTP, TCP, SSH and more (JA4+)

Who Uses This, and For What

TLS fingerprinting is genuinely dual-use. On the defensive side, it is one of the more useful tools a network operator has. A fingerprint that claims to be Chrome in its User-Agent header but whose ClientHello matches Python’s requests is almost certainly a bot lying about itself. Security teams use JA3/JA4 to spot malware beaconing, to cluster automated traffic, and to flag scrapers that don’t match any real browser. Because the fingerprint is computed from bytes the client cannot easily fake without rebuilding its TLS stack, it is harder to spoof than a header.

That same strength is what makes it a censorship and tracking tool. A national firewall or a corporate middlebox can fingerprint every outbound connection and treat traffic differently based on what software produced it — throttling or blocking a circumvention tool whose handshake doesn’t look like a mainstream browser, even though it cannot read the encrypted payload. Anti-bot vendors and CDNs fingerprint connections to decide who gets served and who gets a challenge. The fingerprint becomes a passive selector applied before you have proven anything about who you are.

The encryption is doing its job perfectly. The leak is in the envelope, not the letter — and the envelope is, by necessity, written in the clear.

Can You Defend Against It?

Not cleanly, and that is the uncomfortable part. Because the fingerprint is derived from how your TLS library behaves, the only thorough defense is to make your traffic produce a common, unremarkable fingerprint — to look like everyone else. Circumvention tools increasingly do exactly this through uTLS, a Go library that lets a client mimic the precise ClientHello of a mainstream browser, GREASE and ordering included, so its JA3/JA4 blends into the crowd.

For an ordinary user, the practical reality is simpler: using a current, mainstream browser is itself a form of crowd-blending, because millions of others produce a near-identical handshake. The danger zone is unusual software — a custom client, an old library, a niche tool — that produces a rare fingerprint precisely because few others share it. This is the same logic that governs browser fingerprinting at the application layer: distinctiveness is the vulnerability, and the anonymity set is the defense.

The Broader Lesson

TLS fingerprinting is a clean illustration of a pattern that runs through nearly all privacy engineering: encrypting the contents of a channel does not hide the channel’s metadata, and the metadata is often enough. The handshake has to be in the clear so two strangers can agree on a key. The shape of that handshake leaks the identity of the software making it. No amount of payload encryption closes that gap, because the gap exists before encryption begins.

The honest takeaway is not that TLS is broken — it isn’t — but that “the connection is encrypted” answers a narrower question than most people think. Knowing what your tools reveal in the clear, and choosing tools whose visible behavior is common rather than distinctive, is the part of the threat model that fingerprinting forces you to take seriously.

Originally published at havenmessenger.com