BAD SKY.NET

TLS Fingerprint Checker

See how servers and anti-bot systems see your client: JA3, JA4, HTTP/2 fingerprint and header order. See statistics

Check your scraper

Run one of these from your script or server and compare the verdict with what you expect.

curl
curl https://tls.badsky.net:4443/json
Python (requests)
import requests

print(requests.get('https://tls.badsky.net:4443/json').json())
Python (curl_cffi)
from curl_cffi import requests

print(requests.get('https://tls.badsky.net:4443/json', impersonate='chrome').json())
PHP
<?php

echo file_get_contents('https://tls.badsky.net:4443/json');
Node.js
const response = await fetch('https://tls.badsky.net:4443/json')
console.log(await response.json())

FAQ

What is a JA3 fingerprint?

JA3 is an MD5 hash of the TLS ClientHello fields a client sends: version, cipher suites, extensions, elliptic curves and point formats. The same software produces the same JA3, so servers use it to recognize clients regardless of the User-Agent. Chrome and Firefox randomize extension order, which makes JA3 unstable for them, and that is why JA4 exists.

What is a JA4 fingerprint?

JA4 is the successor of JA3. It sorts ciphers and extensions before hashing, so browsers that shuffle extensions keep one stable value, and it adds readable prefixes: protocol, TLS version, SNI, ALPN and counts. This page shows the JA4 TLS client fingerprint only.

Why does curl get blocked even with browser headers?

Anti-bot systems compare your headers with your TLS and HTTP/2 handshake. Plain curl or Python requests send a handshake that no browser sends, so a Chrome User-Agent on top of it is a mismatch and a strong bot signal. Use a client that reproduces the browser handshake, such as curl-impersonate or curl_cffi.

Does a proxy change my TLS fingerprint?

No. An HTTP (CONNECT) or SOCKS proxy tunnels your TLS handshake end to end, so the server sees your client's fingerprint, only from a different IP. Only a TLS-terminating proxy changes the fingerprint.

What is curl-impersonate?

curl-impersonate is a build of curl that sends the same TLS and HTTP/2 handshake as Chrome, Firefox or Safari, including cipher order, extensions and HTTP/2 settings. Its Python binding is curl_cffi. Test it here: your verdict should read as a browser.