JA3 was published by Salesforce engineers in 2017 as a way to recognise client software from the first message of a TLS handshake. It takes five fields from the ClientHello, joins them into a string, and hashes the string with MD5:

TLSVersion,Ciphers,Extensions,EllipticCurves,EllipticCurvePointFormats
771,4865-4866-4867-49195,0-23-65281-10-11,29-23-24,0

Values within a field are joined with dashes, in the order the client sent them. The hash of that string is the JA3 fingerprint, and a given library on a given version tends to produce the same one every time.

Why it lost its edge

JA3 hashes the order as sent. Since Chrome 110 in early 2023, Chrome shuffles the order of its TLS extensions on every connection, so one Chrome browser produces many different JA3 hashes. The Salesforce repository was archived in 2025, and JA4, which sorts before hashing, has largely taken its place. You will still meet JA3 in older blocklists, log formats and write-ups.

Why it matters with proxies

A TLS fingerprint belongs to your client, not your IP. HTTPS traffic passes through a proxy inside an encrypted tunnel, so the ClientHello reaches the site untouched: switching proxies never changes your JA3. Changing the client does, which is why tools such as curl_cffi impersonate browser handshakes.

How to see yours

curl -s https://tls.peet.ws/api/all

The response includes ja3 and ja3_hash for the connection it received. TLS fingerprinting with curl_cffi compares the values from requests, curl_cffi and a browser.