TLS and TCP fingerprinting: what JA3 and JA4 actually see
TLS and TCP fingerprinting: what JA3 and JA4 actually see
most people chasing browser fingerprinting spend their energy on canvas hashes, WebGL renderers, and font lists. those matter. but there is a layer underneath all of that, one that fires before your browser even loads a page, before JavaScript runs, before any of your carefully spoofed browser attributes are visible. that layer is your TLS handshake, and it tells the server exactly what kind of client is connecting, regardless of what your user-agent header claims.
i spent a while confused about why some residential proxies triggered fraud scores even with a clean browser profile. the answer, once i dug into it, was often TLS. the proxy software or the automation library underneath was advertising itself in the handshake. understanding JA3 and JA4 is the first step to understanding why that happens and what you can actually do about it.
what it is
TLS fingerprinting is the practice of identifying a client, a browser, a bot, a proxy tool, or anything else making an HTTPS connection, based on the specific parameters it sends during the TLS handshake. the handshake happens before any HTTP traffic is exchanged. it is the negotiation where client and server agree on which encryption methods to use.
JA3 is the original fingerprinting method, introduced by John Althouse, Jeff Atkinson, and Josh Atkins at Salesforce in 2017. it takes several fields from the TLS ClientHello message, specifically the TLS version, cipher suites, extensions, elliptic curves, and elliptic curve point formats, concatenates them in a defined order, and runs MD5 over the result. you get a 32-character hex hash. every distinct combination of those fields produces a different hash.
JA4 is the successor, also by John Althouse, now at FoxIO. it was published in 2023 and addresses several weaknesses in JA3, most importantly that JA3 was order-dependent, meaning randomizing cipher suite order changed the hash even when the underlying software was the same. JA4 sorts the values before hashing, making it more stable. it also produces a human-readable fingerprint string before the hash, which makes analysis much easier. JA4 is a fingerprint suite, not just one hash. JA4+ extends it further to cover TCP, HTTP/2, and other protocol layers.
how it works
when your browser or any TLS client initiates an HTTPS connection, it sends a ClientHello message to the server. this message is defined in RFC 8446, the TLS 1.3 specification. it contains a list of cipher suites the client supports, in preference order. it contains a list of extensions, each with its own parameters. it contains supported groups (elliptic curves) and signature algorithms.
the server sees all of this before it sends back a single byte of application data. a detection system sitting at or behind the server can hash these fields immediately and compare against a database of known fingerprints.
here is what a JA3 hash is actually built from:
- SSLVersion: the version field in the ClientHello
- Ciphers: the list of cipher suite codes, comma-separated
- Extensions: the list of extension type codes
- EllipticCurves: supported groups extension values
- EllipticCurvePointFormats: point format extension values
these are joined with dashes between categories and commas between values within a category, then MD5-hashed. a real Chrome 120 on Windows has a specific JA3. curl has a different one. python-requests has another. headless Chromium driven by Playwright often has a slightly different one from a real Chrome install because the extension list differs.
JA4 improves on this. the format looks like t13d1516h2_8daaf6152771_e5627ade68d0 before hashing. the first segment encodes protocol version, SNI presence, number of ciphers, number of extensions, and ALPN. because it is human-readable, a security analyst can look at it and immediately understand something about the client without needing a lookup table.
TCP fingerprinting runs at a lower layer still. tools like p0f and the original Salesforce JA3 repository note that TCP parameters, specifically the initial TTL, window size, and TCP options in the SYN packet, are also characteristic of specific operating systems and network stacks. combining TLS and TCP fingerprints makes it possible to detect mismatches: a ClientHello that claims to be Chrome on Windows but arrives with a Linux TCP stack is a red flag.
why it matters
proxy and automation detection. many commercial proxies route your traffic through software that generates its own TLS handshake, not the one your browser would produce. if you are using a Python-based scraper behind a residential proxy, the proxy handles the HTTPS connection. the target site sees a Python SSL library fingerprint, not a Chrome fingerprint. this is a common reason why otherwise clean proxies get flagged. proxyscraping.org’s blog has useful coverage of how proxy traffic is detected at the network layer, which complements what i am describing here.
account integrity checks. platforms that care about account quality, large e-commerce sites, financial platforms, airdrop programs, do not only check your cookies and browser attributes. some run TLS fingerprint checks on login and on sensitive actions. an account that logged in with one TLS signature and now makes requests with a completely different one triggers an anomaly.
bot detection services. Cloudflare, Akamai, and DataDome all incorporate TLS fingerprinting into their scoring. Cloudflare’s bot management documentation explicitly mentions client fingerprinting at the TLS layer as a signal. a high JA3 reputation score means many bots have used that fingerprint. curl and certain Selenium configurations have JA3 hashes that are basically permanently burned.
security research and threat hunting. on the defensive side, JA3 is used to identify malware families by their TLS behavior. a piece of malware using a custom TLS implementation has a distinctive ClientHello. this is actually where JA3 originated: detecting command-and-control traffic in enterprise networks. if you want to understand how detection engineers think, knowing this context helps.
common misconceptions
“a residential proxy fixes my TLS fingerprint.” no. a residential proxy changes your IP address. it does not change the TLS stack making the connection. if the proxy client is written in Go or Python, that is what the server fingerprints. the IP address is residential but the TLS fingerprint is a datacenter automation tool. you need a solution that passes TLS termination to a real browser process, not just routes your IP through a residential exit node.
“rotating my user-agent rotates my TLS fingerprint.” the user-agent is an HTTP header. TLS happens before HTTP. they are completely independent layers. you can set any user-agent you want and your JA3 will not change by a single bit.
“JA3 is unique per device.” JA3 identifies software, not individual machines. every Chrome 124 install on Windows using the same version and patch level will produce the same JA3 hash. it is a software signature, not a device ID. this also means that sharing a fingerprint with millions of real Chrome users is actually desirable from a detection standpoint.
“HTTPS means the fingerprint is encrypted.” the ClientHello in TLS 1.3 is sent before encryption is established. that is the whole point of the handshake: it negotiates the keys. some extensions like Encrypted Client Hello (ECH) are working to encrypt parts of the ClientHello, but as of mid-2026 ECH deployment is still limited and the core cipher and extension lists remain visible to any in-path observer, including the server you are connecting to.
where to go from here
if this is your first time thinking about the network layer as a fingerprint surface, there are a few logical next topics:
- browser fingerprinting basics covers the application-layer signals that complement TLS fingerprinting, canvas, fonts, WebGL, and how detection systems combine them.
- antidetect browsers explained goes into how tools like Multilogin and AdsPower handle browser-level fingerprint isolation, and where TLS passthrough fits into their architecture. for the account operations side of this, multiaccountops.com/blog/ covers practical multi-account setups where fingerprint consistency across layers is critical.
- residential proxies: how they actually work explains the difference between IP routing and TLS termination, which is directly relevant to the misconceptions section above.
- the JA4 specification on GitHub is worth reading directly. the README explains the design decisions clearly, and seeing the actual field order helps build intuition faster than any secondary explanation.
browse the full antidetectreview.org/blog/ for more fingerprinting, proxy, and multi-account operations coverage.
Written by Xavier Fok
disclosure: this article may contain affiliate links. if you buy through them we may earn a commission at no extra cost to you. verdicts are independent of payouts. last reviewed by Xavier Fok on 2026-05-19.