10% off ALL new Proxies – CODE: 10pro

TLS Fingerprinting Explained: JA3, JA4 and Consistency

TLS Fingerprinting Explained: JA3, JA4 and Consistency

Direct Answer

TLS fingerprinting identifies the software making a connection by reading the details of its TLS handshake — the cipher list, extensions, elliptic-curve groups and version, in the exact order the client sends them — and hashing them into a signature such as JA3 or JA4. A Python script and a real browser produce different signatures, and a proxy changes your IP, not this handshake.

→ Scoping a target? The free anti-bot detector shows which bot-protection vendor guards a site before you send traffic.


What Is TLS Fingerprinting?

Every HTTPS connection begins with a TLS handshake, before a single byte of the actual web page is exchanged. The very first message the client sends is called the ClientHello, and it is surprisingly revealing. In it, the client announces the TLS versions it supports, the list of cipher suites it prefers (in order), the extensions it wants to use, the elliptic-curve groups it accepts, and several other parameters. None of this is secret — it has to be sent in the clear so the server can pick compatible settings.

The catch is that different software builds this ClientHello differently. Chrome's TLS engine, Firefox's, a Python script's OpenSSL, Go's standard library, a curl build — each one lists its ciphers and extensions in its own characteristic order, with its own set of supported features. Those choices are stable per software version, so if you record them and hash the result, you get a signature that says which client stack opened the connection. That is TLS fingerprinting, and it happens at the network edge, before your request ever reaches an application.

This is a close cousin of browser fingerprinting, but one layer lower. Browser fingerprinting reads traits inside the browser with JavaScript after the page loads. TLS fingerprinting reads the connection itself during the handshake — so it works even against a headless script that never runs any JavaScript at all.


JA3, and the Move to JA4

The best-known way to express a TLS fingerprint is JA3, published by Salesforce engineers in 2017. JA3 takes five fields from the ClientHello — TLS version, cipher suites, extensions, elliptic curves and curve formats — concatenates them in order, and produces an MD5 hash. Two connections with the same JA3 hash almost certainly came from the same kind of client software. There is a server-side counterpart, JA3S, that fingerprints the ServerHello response the same way.

JA3 served the industry for years, but it had weaknesses. Because it collapses everything into one MD5, a small change in extension order flips the whole hash, and modern browsers deliberately shuffle some extensions to resist exactly this kind of tracking — which made raw JA3 noisier over time.

JA4 and its wider family (often written JA4+) were introduced to address that. Instead of one opaque hash, JA4 records the handshake in a structured, partly human-readable form: it sorts the fields that browsers randomise, keeps the ones that stay stable, and separates the TLS layer from the HTTP layer. The family includes JA4H for HTTP request fingerprinting (method, headers, header order, cookies) and further members for TLS server hellos and other protocols. Because JA4 is more robust to deliberate randomisation, it has been adopted broadly — variants of the JA4+ approach now appear across major anti-bot and CDN platforms such as Cloudflare, AWS and Akamai as part of their bot-detection tooling. The exact scoring each vendor applies is proprietary, so treat any specific claim about thresholds with caution; the underlying mechanism, however, is well documented and open.

The takeaway is not the acronym. It is that the transport layer alone now carries a reliable identifier of your client software, independent of anything you put in your headers.


Why a Python Client Looks Different From a Browser

Here is the practical heart of the matter for anyone doing data work. Suppose you write a scraper in Python using the requests library and set the user-agent header to a current version of Chrome. On the surface, your request claims to be Chrome. But requests opens its connection through OpenSSL, which sends an OpenSSL-shaped ClientHello — a cipher and extension list that no real Chrome build produces.

An anti-bot system sees the contradiction instantly:

  • The user-agent header says "I am Chrome on Windows."
  • The TLS fingerprint says "I am an OpenSSL-based script."

Those two facts cannot both be true for an ordinary visitor. Real Chrome always sends Chrome's handshake. The mismatch is not something the site has to guess at — it is a hard, structural inconsistency, and it is one of the cheapest, most reliable bot signals available. The same applies to curl, to Go's default HTTP client, to Node's built-in fetch, and to any tool whose TLS stack differs from the browser it claims to be. This is a large part of why datacenter-based automation gets flagged so readily — see why datacenter proxies get blocked and the broader picture in how websites detect proxies.

The honest fix is a matching stack, not a trick

The right response to this is not to hunt for a clever way around the check. It is to make your client actually consistent: if you want to present as a browser, drive a real browser (or an HTTP client whose TLS stack is built to match one), so the handshake and the headers agree because they genuinely belong together. Tools exist in the scraping ecosystem that reproduce browser-accurate TLS handshakes for exactly this reason. That is consistency, not evasion — you are making your client tell one coherent story rather than two contradictory ones.


Cross-Layer Consistency Is What Actually Gets Checked

TLS fingerprinting is rarely used in isolation. Modern anti-bot systems combine several independent layers and look for agreement between them. Think of at least three:

Layer What it reveals How it is read
Network / IP Address, location, network type, reputation The IP the connection comes from
TLS handshake Which client software opened the connection (JA3 / JA4) The ClientHello, before any page loads
HTTP + headers Claimed browser, header set and order (JA4H), user-agent The request itself

An ordinary visitor is consistent across all three: a residential or mobile IP, a real browser's TLS handshake, and matching HTTP headers that agree with that browser. Trouble starts when the layers disagree. A datacenter IP with a browser-perfect handshake still looks off because of the IP. A pristine residential IP paired with an OpenSSL handshake and a Chrome user-agent looks off because the transport contradicts the header. The system does not need a single "gotcha" — it scores the coherence of the whole picture.

This is why chasing one layer in isolation backfires. Rotating IPs endlessly while every request still carries the same tell-tale OpenSSL handshake does not help; the sessions remain linkable and flaggable by their transport signature. Likewise, a flawless browser handshake coming from an IP range with poor IP reputation still draws scrutiny. The passive traits your connection emits even lower down — at the TCP/IP level — add yet another consistency layer, which we cover in browser and passive OS fingerprinting on mobile proxies.


What a Mobile Proxy Does and Does Not Solve

It is worth being precise about the division of labour, because overselling here is common and we would rather be honest.

A German mobile proxy does one job extremely well: it gives your traffic a real, high-trust German mobile IP. Mobile IPs sit behind CGNAT, where thousands of genuine subscribers share each public address, so a site cannot treat that address as a single automated client. That is why mobile IPs carry the highest baseline trust of any proxy type. It is the correct tool for the network layer — the IP-reputation half of the equation.

What a proxy does not do is change your TLS fingerprint. The handshake is generated by your client software on your machine and passes through the proxy untouched. Route through a hundred different mobile IPs and your JA3 or JA4 signature stays byte-for-byte identical, because the proxy never rewrites the ClientHello — it only forwards it.

So the realistic mental model is two complementary layers:

  • The IP layer — a clean, trusted German mobile IP. This is the part GermanProxy.io handles: real German 5G mobile IPs over HTTP, SOCKS5 and OpenVPN, with sticky sessions and on-demand rotation and fair-use 20 GB/day.
  • The client layer — a coherent HTTP/TLS stack whose handshake matches the browser it claims to be. This is the part your setup handles, by driving a real browser or a browser-accurate client rather than a bare scripting default.

When both agree — a real German mobile IP and a client that presents one consistent story from the TLS handshake up through the headers — the session simply looks like what it is: an ordinary German mobile user. That is the whole point. And it pairs naturally with polite client behaviour: honour robots.txt, keep request rates human-paced, and work with public data only, which is the positioning we build on rather than a footnote.


FAQ

What is a TLS or JA3/JA4 fingerprint?

It is a signature computed from the way your client opens an encrypted connection. During the TLS handshake, the client sends a ClientHello that lists its supported cipher suites, extensions, elliptic-curve groups and TLS version in a specific order. JA3 hashes those fields into one string; the newer JA4 family records them in a more structured, robust way. The signature identifies the software — a browser, a scripting library, a command-line tool — before any web page has loaded.

Why does a Python requests script have a different TLS fingerprint than a browser?

Because they use different TLS stacks. A real browser negotiates the handshake through its own engine (BoringSSL in Chrome, NSS in Firefox), which sends a very specific, well-known set of ciphers and extensions in a particular order. A plain Python script using requests goes through OpenSSL, which produces a different ClientHello. Anti-bot systems know both signatures, so a script claiming a Chrome user-agent but sending an OpenSSL handshake is an obvious contradiction.

Does a proxy change my TLS fingerprint?

No. A proxy operates at the network layer and changes the IP address a site sees. The TLS handshake is generated by your client software and passes through the proxy unchanged, so your JA3 or JA4 signature stays identical no matter which IP you route through. The two are independent layers — a clean mobile IP and a consistent client stack solve different halves of the same problem.


CTA

A mobile proxy fixes the IP layer — a real German mobile IP with high baseline trust, so your traffic reads as ordinary consumer traffic while your own client keeps its TLS and HTTP layers consistent. Our German 5G mobile proxies run on real CGNAT mobile networks with HTTP, SOCKS5 and OpenVPN, and fair-use 20 GB/day. Start with what a mobile proxy is.


Get a German mobile proxy: Real 4G/5G IPs from Germany, fair-use 20 GB/day — see German 4G/5G mobile proxy options or try a shared 5G German proxy.

Telegram Support
Nach oben scrollen