Orange textured background

Glossary / technique

TLS/JA3 fingerprinting

TLS/JA3 fingerprinting identifies a client by the shape of its TLS ClientHello message: the specific combination of cipher suites, TLS extensions, elliptic curves, and curve point formats it advertises during a handshake. Because TLS stacks differ across clients, this combination produces a compact hash that distinguishes one client implementation from another at the network layer, before any application code runs.

When a browser or any TLS client opens a secure connection, it sends a ClientHello message that lists the cipher suites it supports, the TLS extensions it wants, and the elliptic curves it accepts. The JA3 method, introduced publicly by Salesforce researchers, concatenates specific numeric fields from that message and MD5-hashes the result into a 32-character string. JA3S extends the same idea to the server's ServerHello response, producing a pair that characterises both sides of the handshake.

Because the TLS ClientHello is sent before the HTTP request, JA3 fingerprinting happens entirely at the network layer. A server or reverse proxy can compute the hash from the raw TCP stream without executing any JavaScript, making it one of the few fingerprinting methods that is genuinely server-side and not defeatable by disabling JS.

The technique has practical limits. Many TLS client libraries randomise extension order or allow callers to configure cipher suites, so different instances of the same library can produce different JA3 hashes. CDN and load-balancer termination often normalises or strips TLS parameters before the origin server sees them, breaking hash consistency. Anti-detect tools and some browsers deliberately shuffle ClientHello fields to impersonate other clients. As a result, JA3 is most useful as a coarse-grained signal, one factor in a layered detection stack rather than a standalone identifier.

In doorman-benny

doorman-benny is a client-side JavaScript library that collects browser and device signals from the DOM and browser APIs. TLS handshake data lives at the network layer and is not accessible to JavaScript running in a page, so Benny does not collect or hash JA3 parameters. JA3 fingerprinting is conceptually complementary: a server-side TLS hash and a client-side device fingerprint each observe different signal surfaces, and combining them at the application layer gives a more complete picture than either alone.

Frequently asked questions

What is a JA3 fingerprint?

A JA3 fingerprint is an MD5 hash of specific fields from a TLS ClientHello message: the TLS version, cipher suites, extensions, elliptic curves, and curve point formats. It characterises the TLS stack a client uses rather than the device or browser content environment.

Can JA3 fingerprinting be spoofed?

Yes. Clients can randomise extension order, configure custom cipher suites, or deliberately copy the ClientHello profile of a different client. Some TLS libraries provide settings specifically for this purpose, and anti-detect tooling commonly applies such spoofing. JA3 hashes should therefore be treated as a probabilistic signal, not a definitive identifier.

Does JA3 fingerprinting work through a CDN?

Usually not at the origin server. CDNs and load balancers terminate TLS connections themselves, so the origin sees the CDN's own TLS stack rather than the client's. JA3 collection must happen at the edge, before TLS termination, to capture the real ClientHello.

How does JA3 fingerprinting differ from browser fingerprinting?

JA3 fingerprinting operates at the network layer using TLS handshake parameters; browser fingerprinting runs JavaScript in the browser to collect rendering, hardware, and API signals. JA3 requires no JS and sees through JS-blocking, but it has lower entropy and is more easily spoofed than rich client-side device fingerprints.

What is the difference between JA3 and JA3S?

JA3 hashes the client's ClientHello fields to fingerprint the client's TLS stack. JA3S hashes the server's ServerHello fields and is used to fingerprint a server's TLS configuration. In bot detection the client-side JA3 hash is the primary signal; JA3S is sometimes paired with it to characterise the full connection.