fingerprintby Scraping Central
Menu

TLS & HTTP transport

Your TLS Handshake, Reflected Back

What the front-end web server saw at the transport layer, plus any JA3 / JA4 the edge chose to publish.

TLS & HTTP transport

Fetching /api/tls.php...

What you can and can't see

This site sits on a shared web host that terminates TLS itself and only surfaces the highlights (version, cipher, ALPN, SNI) to PHP. That's already enough to tell TLS 1.2 from 1.3, HTTP/1.1 from HTTP/2, and to guess your cipher family. Full JA3 / JA4 hashes require a TLS-terminating proxy that writes them as a request header.

TLS-layer signals to watch

  • TLS 1.0 / 1.1 = ancient client, likely misconfigured library.
  • TLS 1.3 with AES-128-GCM = modern Chromium default.
  • TLS 1.3 with CHACHA20 = mobile browser or Firefox on ARM.
  • ALPN missing entirely = a very old HTTP library.
  • HTTP/1.1 on a modern browser UA = suspicious (real Chrome negotiates HTTP/2 wherever possible).

Note on TCP

TCP-level fingerprinting (initial window size, MSS, TCP options order) can also identify OSes, but it lives below PHP's reach on shared hosting. It shows up in commercial anti-bot products via kernel-level probes at the edge.

Frequently asked questions

What is TLS fingerprinting?

The TLS ClientHello a browser sends is far richer than the eventual application-layer HTTP: it lists cipher suites in a specific order, advertises extensions in a specific order, includes elliptic curves, signature algorithms, and ALPN protocols. Each real browser has a distinctive shape. JA3 and JA4 are two ways to hash that shape into a fingerprint string.

Can PHP see the JA3/JA4 fingerprint?

Only if the front-end proxy or load balancer computes it and forwards it as a request header. Cloudflare exposes cf-ja3 / cf-ja4 with Bot Management enabled; HAProxy can be configured to add JA3 via a Lua script; nginx needs the ssl-ja3 module. If your host doesn't do any of that, PHP sees nothing.

Why do HTTP libraries fail TLS fingerprint checks?

Because Python's requests uses OpenSSL, Go uses crypto/tls, curl uses whatever it was compiled against. Each library has its own ClientHello shape, distinctly different from real Chrome / Firefox / Safari. Anti-bot vendors keep pre-computed JA3 hashes for every popular library and match incoming traffic against them.

How do scrapers get around TLS fingerprinting?

Two main approaches. First, wrap a library that replicates a real browser's ClientHello: curl_cffi (Python), utls (Go), Node's undici with the right SSL_CIPHER_LIST. Second, drive a real headless browser, which by definition speaks like a real browser. The latter is more reliable but heavier.

What does HTTP/2 vs HTTP/3 change?

HTTP/2 has its own fingerprint: the SETTINGS frame values, the header table size, the initial window, the priority tree, and the header order all differ per client. Akamai and Cloudflare compute HTTP/2 fingerprints on top of TLS ones. HTTP/3 (QUIC) is even more identifying because it moves TLS into UDP and adds its own transport parameters.

← Run the full fingerprint report

AI Summary

Summarize this page in your favorite LLM