
TLS Fingerprinting and JA3: How Your Encrypted Connection Betrays Your Identity
Even if you’ve mastered every browser-level fingerprinting defense — canvas spoofing, WebGL protection, user agent randomization — there’s a layer of tracking that operates beneath the browser itself: TLS fingerprinting JA3 explained in simple terms, it’s a technique that identifies your client software by analyzing the way it initiates encrypted connections, before a single byte of website content is exchanged.
Every time your browser connects to an HTTPS website, it sends a TLS ClientHello message — the opening handshake of the encrypted connection. This message contains a structured list of cryptographic capabilities: which cipher suites the client supports, which TLS extensions it uses, which elliptic curves it prefers, and which signature algorithms it accepts. While this data is essential for establishing a secure connection, it also creates a unique fingerprint of the client software.
In 2026, TLS fingerprinting has become a standard tool for CDN providers like Cloudflare and Akamai, anti-bot services, and fraud detection platforms. The JA3 hash — and its successor JA4+ — can instantly distinguish a real Chrome browser from a Python requests script, a headless browser, or even a different version of Chrome. This guide explains exactly how it works, why it’s exceptionally hard to spoof, and how cloud-based browsers like Send.win naturally present clean, legitimate TLS fingerprints.
Anatomy of the TLS ClientHello Message
To understand TLS fingerprinting, you need to understand what the ClientHello message contains and why each field matters for identification. The ClientHello is the very first message sent by the client (your browser) to the server when initiating an HTTPS connection. To understand how TLS fingerprinting fits into the broader fingerprinting landscape, see our complete browser fingerprint explained guide.
TLS Version
The ClientHello specifies the maximum TLS version the client supports. In 2026, virtually all modern browsers support TLS 1.3, but the way they indicate this varies:
- Chrome/Chromium: Sends TLS 1.2 in the record layer with a
supported_versionsextension listing TLS 1.3 - Firefox: Same approach, but the extension ordering differs
- Safari: Similar pattern with subtle differences in extension presentation
- Older clients: May only support TLS 1.2 or even TLS 1.1
Cipher Suites
The cipher suite list is one of the most distinguishing fields in the ClientHello. It specifies which encryption algorithms the client supports, in order of preference. Here’s how major browsers differ:
| Browser | Typical Cipher Suite Count (TLS 1.3 + 1.2) | Notable Characteristics |
|---|---|---|
| Chrome 130+ | 15-17 | Includes GREASE values, specific ordering of TLS 1.3 suites |
| Firefox 128+ | 14-16 | Different ordering, includes Chacha20 prioritized on non-AES-NI hardware |
| Safari 18+ | 12-14 | More conservative list, Apple-specific ordering |
| Python requests | 10-18 | OpenSSL default list, instantly identifiable |
| curl | Varies | Depends on compiled TLS library (OpenSSL, LibreSSL, BoringSSL, etc.) |
| Go net/http | 5-7 | Minimal list, very distinctive |
TLS Extensions
TLS extensions add capabilities beyond the basic handshake. The number, type, and order of extensions are highly identifying:
- server_name (SNI): Contains the hostname being connected to — not fingerprint-relevant but present in most clients
- supported_versions: Lists supported TLS versions (1.2, 1.3)
- signature_algorithms: Which signature schemes the client supports for certificate verification
- supported_groups (elliptic curves): Which named groups/curves are supported for key exchange
- ec_point_formats: Elliptic curve point format support
- application_layer_protocol_negotiation (ALPN): Advertises HTTP/2 and HTTP/3 support
- key_share: Pre-computed key exchange values for TLS 1.3 0-RTT
- psk_key_exchange_modes: Pre-shared key modes
- compress_certificate: Certificate compression support (Brotli)
- encrypted_client_hello (ECH): Encrypts the ClientHello itself — newer privacy feature
- GREASE values: Random “filler” values used by Chrome to prevent extension ossification
Chrome typically sends 16-18 extensions, Firefox sends 14-16, and Safari sends 12-14. The specific set and ordering creates a strong signal.
Elliptic Curves (Supported Groups)
The supported_groups extension lists which elliptic curves and finite field groups the client supports for key exchange. Common entries include:
x25519— Preferred by most modern browserssecp256r1(P-256) — Universal supportsecp384r1(P-384) — Common but not always includedx25519_kyber768— Post-quantum hybrid key exchange (Chrome 2024+)ffdhe2048,ffdhe3072— Finite field Diffie-Hellman groups
The inclusion of post-quantum algorithms like x25519_kyber768 (now called x25519_mlkem768 in 2026) is a strong indicator of a recent Chromium-based browser. Its presence or absence, combined with the ordering of other curves, helps narrow down the exact browser version.
Signature Algorithms
The signature_algorithms extension specifies which digital signature schemes the client accepts for authenticating the server’s certificate. This list varies significantly between browsers and versions, adding another layer of fingerprint entropy.
How JA3 Hashing Works
JA3 was created by John Althouse, Jeff Atkinson, and Josh Atkins at Salesforce in 2017. It’s a method for creating a fingerprint hash from the TLS ClientHello message. Here’s the process:
JA3 Hash Computation
- Extract five fields from the ClientHello:
- TLS version (decimal)
- Cipher suites (comma-separated decimal values)
- Extensions (comma-separated decimal values)
- Elliptic curves (comma-separated decimal values)
- Elliptic curve point formats (comma-separated decimal values)
- Join with dashes:
TLSVersion,CipherSuites,Extensions,EllipticCurves,ECPointFormats - MD5 hash: Compute the MD5 hash of the concatenated string
The result is a 32-character hex string like e7d705a3286e19ea42f587b344ee6865 that uniquely identifies the client’s TLS configuration.
JA3 Example
A simplified JA3 string for Chrome might look like:
771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0
This gets MD5-hashed to produce the final JA3 fingerprint. The same browser version on the same OS will always produce the same JA3 hash (with minor exceptions for GREASE randomization).
JA3S: Server-Side Fingerprinting
JA3S applies the same concept to the server’s ServerHello response. It fingerprints the server’s TLS configuration using:
- TLS version
- Selected cipher suite
- Extensions
JA3S is useful for identifying specific server software and detecting man-in-the-middle proxies. When combined with JA3, the (JA3, JA3S) pair provides an even more precise identification of the client-server relationship.
JA4+ : The Evolution Beyond JA3
JA4+, released by FoxIO in 2023-2024, addresses several limitations of JA3 and has become the de facto standard for TLS fingerprinting in 2026:
Key Improvements Over JA3
| Feature | JA3 | JA4+ |
|---|---|---|
| Hash algorithm | MD5 (collision-prone) | SHA256 (truncated to 12 chars) |
| GREASE handling | Included (causes hash instability) | Excluded (stable hashes) |
| Human readability | Opaque hex string | Structured prefix (e.g., t13d1516h2_) |
| Extension ordering | Original order (varies with GREASE) | Sorted alphabetically (more stable) |
| Coverage | TLS only | TLS, HTTP, SSH, X.509 certificates |
| QUIC/HTTP3 | Not supported | Dedicated JA4Q fingerprint |
JA4 Fingerprint Structure
A JA4 fingerprint has a human-readable prefix followed by a hash:
t13d1516h2_8daaf6152771_e5627efa2ab1
Breaking this down:
t— Protocol (t = TCP/TLS, q = QUIC)13— TLS version 1.3d— SNI present (d = domain, i = IP)15— Number of cipher suites16— Number of extensionsh2— First ALPN value (HTTP/2)_8daaf6152771— SHA256 hash of sorted cipher suites_e5627efa2ab1— SHA256 hash of sorted extensions + signature algorithms
This structure means security analysts can immediately tell the TLS version, approximate client type, and protocol support just by looking at the prefix — without needing to decode the hash.
The JA4+ Family
JA4+ includes multiple fingerprint types:
- JA4: TLS ClientHello fingerprint
- JA4S: TLS ServerHello fingerprint
- JA4H: HTTP client fingerprint (headers, cookies, methods)
- JA4X: X.509 TLS certificate fingerprint
- JA4SSH: SSH fingerprint
- JA4T: TCP fingerprint (window size, options, MSS)
- JA4Q: QUIC fingerprint (for HTTP/3 connections)
Why TLS Fingerprinting Is Exceptionally Hard to Spoof
Unlike browser-level fingerprinting (canvas, WebGL, fonts), TLS fingerprinting operates at the network level — below the browser’s JavaScript engine. This makes it fundamentally harder to manipulate:
The TLS Stack Is Not JavaScript-Accessible
Browser extensions and JavaScript cannot modify the TLS ClientHello message. The TLS handshake is handled by the browser’s network stack (BoringSSL in Chrome, NSS in Firefox), which runs as native code outside the web content process. No amount of JavaScript injection can change the cipher suite list or extension order.
Proxy-Based Spoofing Introduces Its Own Fingerprint
Some users attempt to modify TLS fingerprints using intercepting proxies (e.g., mitmproxy, utls). The problem: the proxy’s own TLS implementation creates a different fingerprint that may not match any known browser. Worse, the use of a proxy can be detected through timing analysis, HTTP/2 framing differences, and TCP-level signals.
Browser Version Specificity
Each Chrome release (Chrome 125, 126, 127…) has a slightly different TLS fingerprint due to cipher suite changes, new extensions, and GREASE rotation. Perfectly impersonating a specific Chrome version requires matching its exact TLS configuration — information that changes every 4-6 weeks with new releases.
GREASE Complicates Static Matching
Google’s GREASE (Generate Random Extensions And Sustain Extensibility) mechanism inserts random, unknown values into cipher suite and extension lists. This was designed to prevent servers from hardcoding assumptions about ClientHello structure, but it also makes JA3 hashes unstable (the same browser produces different JA3 hashes across connections). JA4 addresses this by ignoring GREASE values, but older JA3-based systems still struggle with it.
CDN and Anti-Bot Detection via TLS Fingerprinting
The practical impact of TLS fingerprinting is most visible in CDN and anti-bot systems. The same CDN providers that protect websites from attacks now use TLS fingerprints to classify incoming traffic. For more on how these systems work, check our guide on anti-bot detection bypass.
Cloudflare
Cloudflare uses JA3 and JA4 fingerprints as part of its Bot Management product. Their system:
- Maintains a database of known browser JA3/JA4 hashes
- Flags connections whose TLS fingerprint doesn’t match their claimed user agent
- Blocks or challenges connections with TLS fingerprints matching known automation tools (Python requests, Go http, etc.)
- Uses JA4+ for more granular classification, including HTTP header fingerprinting
Akamai
Akamai pioneered TLS fingerprinting with their 2019 research on identifying bot traffic. Their system:
- Classifies traffic into known browser categories based on TLS fingerprints
- Detects curl, wget, and Python-based scrapers with near-100% accuracy
- Identifies headless browsers that don’t perfectly replicate a full browser’s TLS stack
- Cross-references TLS fingerprints with HTTP/2 settings fingerprints for additional confidence
Kasada, DataDome, and PerimeterX
Specialized anti-bot vendors have built sophisticated systems that combine TLS fingerprinting with browser-level signals. A mismatch between the JA3/JA4 hash (network level) and the browser fingerprint (JavaScript level) is a strong indicator of automation or spoofing. This is why automation tools that perfectly spoof browser fingerprints can still get blocked — their TLS fingerprint doesn’t match. Understanding how headless browser detection works helps explain why TLS is such a critical layer.
Common TLS Fingerprint Scenarios and Detection
| Scenario | JA3/JA4 Match | User-Agent Match | Result |
|---|---|---|---|
| Real Chrome browser | ✅ Chrome JA4 | ✅ Chrome UA | ✅ Passes |
| Python requests + Chrome UA | ❌ Python/OpenSSL JA4 | ✅ Chrome UA | ❌ Blocked (TLS mismatch) |
| Puppeteer (headless Chrome) | ✅ Chrome JA4 | ⚠️ HeadlessChrome UA (if not spoofed) | ⚠️ Flagged |
| Puppeteer + stealth plugin | ✅ Chrome JA4 | ✅ Chrome UA | ✅ Usually passes TLS check |
| Go HTTP client + Chrome UA | ❌ Go JA4 | ✅ Chrome UA | ❌ Blocked (TLS mismatch) |
| utls library with Chrome preset | ⚠️ Close but imperfect | ✅ Chrome UA | ⚠️ May pass basic, fails advanced |
| Cloud browser (Send.win) | ✅ Real Chrome JA4 | ✅ Chrome UA | ✅ Passes (genuine browser) |
How Send.win Handles TLS Fingerprinting
Cloud-based antidetect browsers have a fundamental advantage for TLS fingerprinting: they run a real browser on the server. This means:
- Genuine TLS stack: The browser uses its native TLS implementation (BoringSSL for Chromium), producing authentic JA3/JA4 hashes that match known browser fingerprints
- Current browser version: The cloud browser is kept up-to-date, so its TLS fingerprint matches the latest releases — no stale or outdated cipher suite lists
- No proxy artifacts: Because the browser runs directly on the cloud server, there’s no intercepting proxy to introduce TLS anomalies
- Clean HTTP/2 settings: The HTTP/2 SETTINGS frame (another fingerprinting vector) also comes from the real browser, not a proxy or library
- Consistent with browser fingerprint: The TLS fingerprint matches the browser-level fingerprint (canvas, WebGL, etc.) because it’s all from the same genuine browser instance
This is fundamentally different from client-side antidetect browsers, which still use your local machine’s TLS stack. While local antidetect browsers can spoof JavaScript-level fingerprints, they can’t easily modify the TLS ClientHello without using a custom TLS proxy — which introduces its own detection vectors. For more on how automation tools interact with detection systems, see our article on browser automation without detection.
Protection Strategies for TLS Fingerprinting
1. Use a Real Browser (Basic Protection)
The simplest defense: use an actual browser rather than an HTTP library. Real Chrome, Firefox, and Safari produce legitimate JA3/JA4 hashes. However, this doesn’t help if you need multiple identities, as every session from the same browser version will have the same TLS fingerprint.
2. utls / Custom TLS Libraries (Advanced, Partial Protection)
Libraries like Go’s utls can mimic specific browser TLS configurations. They support Chrome, Firefox, and Safari presets. However:
- Presets can lag behind actual browser releases
- Subtle differences in extension encoding may still be detectable
- HTTP/2 settings, header order, and other signals must also match
- Maintaining accurate presets requires constant updates
3. Cloud Browser (Most Effective)
Running a real browser in the cloud (Send.win’s approach) naturally produces clean, authentic TLS fingerprints. There’s nothing to spoof because the TLS handshake originates from a genuine browser. Each cloud profile can use a different IP address and maintain a distinct browsing session while sharing the same authentic TLS behavior.
The Future of TLS Fingerprinting: ECH and Post-Quantum
Two emerging technologies will impact TLS fingerprinting in the coming years:
Encrypted Client Hello (ECH)
ECH encrypts the ClientHello message so that passive observers (ISPs, network admins) can’t read its contents. However, the TLS server still sees the full ClientHello, so server-side TLS fingerprinting (by CDNs and anti-bot services) remains fully functional. ECH primarily protects against network-level surveillance, not server-side fingerprinting.
Post-Quantum Cryptography
The adoption of post-quantum key exchange algorithms (ML-KEM, previously Kyber) in browsers creates a new fingerprinting dimension. Browsers that support post-quantum algorithms produce larger ClientHello messages with distinctive key share extensions. The rollout timeline varies between browsers, creating a temporary period of high fingerprint entropy.
🏆 Send.win Verdict
TLS fingerprinting via JA3/JA4+ is one of the most challenging tracking vectors to defend against because it operates below the browser’s JavaScript layer — no extension, script injection, or browser setting can modify the TLS ClientHello. Client-side antidetect browsers and automation tools either expose their real TLS fingerprint or require complex proxy setups that introduce their own detection artifacts. Send.win solves this elegantly: every cloud browser profile runs a genuine, up-to-date Chromium instance that produces authentic TLS fingerprints matching known browser hashes. No spoofing, no proxies, no mismatches — just a real browser with a clean JA3/JA4 fingerprint that passes Cloudflare, Akamai, and every major anti-bot system.
Try Send.win free today — get genuine TLS fingerprints that pass JA3/JA4 checks on every major platform.
Frequently Asked Questions About TLS Fingerprinting and JA3
What is TLS fingerprinting?
TLS fingerprinting is a technique that identifies client software by analyzing the TLS ClientHello message sent at the beginning of every HTTPS connection. The ClientHello contains structured data about the client’s cryptographic capabilities — cipher suites, extensions, elliptic curves, and signature algorithms — which varies between browsers, versions, and TLS libraries. By examining these fields, a server can determine what software initiated the connection, even if the user agent string has been spoofed.
What is a JA3 hash and how is it calculated?
A JA3 hash is an MD5 fingerprint computed from five fields in the TLS ClientHello message: the TLS version, cipher suites, extensions, elliptic curves, and elliptic curve point formats. These fields are concatenated into a comma-and-dash-separated string, which is then MD5-hashed to produce a 32-character hex string. The same client software will always produce the same JA3 hash (with some variation due to GREASE values in Chrome), making it a reliable identifier for the TLS implementation.
What is the difference between JA3 and JA4?
JA4 is the successor to JA3, created to address several of JA3’s limitations. Key differences include: JA4 uses SHA256 instead of MD5, ignores GREASE values for more stable hashes, sorts extensions alphabetically for consistency, includes a human-readable prefix showing TLS version and client type, and extends coverage to HTTP (JA4H), SSH (JA4SSH), QUIC (JA4Q), and TCP (JA4T). JA4 is now the preferred standard for TLS fingerprinting in 2026.
Can I change my JA3/JA4 fingerprint with a browser extension?
No. Browser extensions operate at the JavaScript level and cannot modify the TLS ClientHello message. The TLS handshake is handled by the browser’s native network stack (BoringSSL in Chrome, NSS in Firefox), which runs outside the web content sandbox. To change your TLS fingerprint, you would need to use a custom TLS proxy, a modified browser build, or a library like utls — all of which introduce their own complexities and potential detection vectors.
Why does Python requests get blocked by Cloudflare when my browser doesn’t?
Python’s requests library uses OpenSSL (or LibreSSL) for its TLS implementation, which produces a completely different JA3/JA4 hash than any real browser. Even if you set a Chrome user agent string, Cloudflare compares the JA3/JA4 hash against known browser fingerprints and immediately detects the mismatch. The TLS fingerprint says “Python/OpenSSL” while the user agent says “Chrome” — a contradiction that triggers Cloudflare’s bot detection. This is why HTTP libraries consistently get challenged or blocked on protected sites.
Does a VPN or proxy change my TLS fingerprint?
A standard VPN or SOCKS proxy does not change your TLS fingerprint. These tools route your traffic through a different network path but don’t modify the TLS handshake — your browser still sends its original ClientHello through the VPN tunnel. However, an intercepting HTTPS proxy (like mitmproxy or corporate proxy) does change the TLS fingerprint because it terminates and re-establishes the TLS connection, creating its own ClientHello to the destination server. This typically makes the fingerprint worse, as the proxy’s TLS configuration rarely matches a real browser.
How does Encrypted Client Hello (ECH) affect TLS fingerprinting?
Encrypted Client Hello (ECH) encrypts the outer ClientHello message, preventing passive network observers (ISPs, network admins) from reading its contents. However, ECH does not prevent server-side TLS fingerprinting — the destination server (and any CDN in front of it, like Cloudflare) still receives and can analyze the full, decrypted ClientHello. So while ECH improves privacy against network surveillance, it does not protect against TLS fingerprinting by the websites you visit.
How does a cloud antidetect browser solve TLS fingerprinting?
A cloud antidetect browser like Send.win runs a real, full browser instance on a remote server. Because the browser uses its native TLS stack (e.g., BoringSSL in Chromium), the TLS ClientHello is genuine and produces authentic JA3/JA4 hashes that match known browser fingerprints. There’s no spoofing or proxying involved — the TLS handshake originates from a real browser, so CDN and anti-bot systems see a legitimate client. This fundamentally solves the TLS fingerprinting problem in a way that client-side tools, custom TLS libraries, and intercepting proxies cannot reliably achieve.
How Send.win Helps You Master Tls Fingerprinting Ja3 Explained
Send.win makes Tls Fingerprinting Ja3 Explained simple and secure with powerful browser isolation technology:
- Browser Isolation – Every tab runs in a sandboxed environment
- Cloud Sync – Access your sessions from any device
- Multi-Account Management – Manage unlimited accounts safely
- No Installation Required – Works instantly in your browser
- Affordable Pricing – Enterprise features without enterprise costs
Try Send.win Free – No Credit Card Required
Experience the power of browser isolation with our free demo:
- Instant Access – Start testing in seconds
- Full Features – Try all capabilities
- Secure – Bank-level encryption
- Cross-Platform – Works on desktop, mobile, tablet
- 14-Day Money-Back Guarantee
Ready to upgrade? View pricing plans starting at just $9/month.
