Articles and comparisons

JA3 and JA4: how the TLS handshake identifies a client

Before a browser sends a single HTTP header, it starts a TLS handshake with a ClientHello message. That message lists the TLS versions, cipher suites and extensions the client supports, and different software builds it differently. JA3 and JA4 turn it into a short fingerprint that says which kind of client is connecting.

Check your browser right now

Checking your browser…

What is in a ClientHello

The ClientHello announces the TLS versions the client accepts, its cipher suites in order of preference, a list of extensions (server name, supported groups, signature algorithms, ALPN for HTTP/2 and others) and their parameters. Chrome, Firefox, Safari, curl, Python libraries and Go programs all produce different combinations, because they use different TLS libraries and settings.

JA3

JA3 was published by researchers at Salesforce in 2017. It concatenates the TLS version, cipher suites, extensions, elliptic curves and point formats from the ClientHello and hashes the result with MD5. The same client software produces the same hash, so it became a common way to recognise malware, scanners and scripts regardless of the User-Agent they claim.

Why JA3 stopped being stable

JA3 keeps the extensions in the order they appear on the wire. In 2023 Chrome started shuffling the order of TLS extensions in every connection, and other browsers followed. The same browser now produces many different JA3 hashes, which makes JA3 much less useful for browsers.

JA4

JA4, released by FoxIO in 2023, fixes this by sorting the cipher suites and extensions before hashing, so the shuffled order no longer matters. It also has a readable first part that encodes the protocol (TLS or QUIC), the TLS version, whether a server name was sent, the number of ciphers and extensions, and the first ALPN value. JA4 is part of a wider family that also covers HTTP requests and server responses.

How sites use TLS fingerprints

The value is in comparison. If the User-Agent header says Chrome on Windows but the TLS handshake looks like a Python library or a Go program, the request almost certainly does not come from that browser. Anti-bot systems at CDNs and large sites check this before the page even loads. HTTP/2 settings and header order give a similar fingerprint one layer up.

TLS fingerprints say which software made the connection, not who the user is. Many people share the same browser version and therefore the same JA4. They work best combined with browser signals, network data and behavior.

Does SpoofLens check this?

Not yet. A TLS fingerprint has to be captured where the TLS connection ends, which our current hosting does not expose. It is planned for a later version on our own servers. Today the SpoofLens check compares what the browser reports in HTTP headers and in JavaScript; BrowserLeaks has a dedicated TLS client test if you need your JA3 or JA4 now.

Frequently asked questions

Is my JA4 fingerprint unique to me?
No. It identifies the client software and its TLS settings. Everyone with the same browser version on the same platform usually shares it.
Can a VPN change my TLS fingerprint?
No. A VPN tunnels the connection but does not change the ClientHello your browser sends.
Why do bots get caught by TLS fingerprints?
Because many scripts use HTTP libraries whose handshake looks nothing like a browser, while they claim a browser User-Agent. The two do not match.

Read next