JA4
JA4 is a fingerprint of the TLS ClientHello, published by FoxIO as the successor to JA3. It identifies the TLS library on the other end of a connection, and unlike JA3 it survives clients that shuffle their extension order.
The shape of one
Three underscore-separated segments, usually written ja4_a _ ja4_b _ ja4_c. Only the first is meant to be read by a human:
t13d1516h2_8daaf6152771_e5627efa2ab1
a t13d1516h2 protocol, TLS version, SNI, counts, ALPN
b 8daaf6152771 sorted cipher suites, hashed
c e5627efa2ab1 sorted extensions + signature algorithms, hashedSegment a, character by character
Ten fixed-width characters. Taking t13d1516h2 apart:
| Chars | Field | Meaning |
|---|---|---|
| t | Transport | t for TCP, q for QUIC, d for DTLS |
| 13 | TLS version | The highest offered, from supported_versions if present. 13 is TLS 1.3 |
| d | SNI | d when the server name is a domain, i when the request went to a bare IP |
| 15 | Cipher count | Cipher suites offered, GREASE excluded, capped at 99 |
| 16 | Extension count | Extensions sent, GREASE excluded, capped at 99. SNI and ALPN are counted here even though they are not hashed below |
| h2 | ALPN | First and last character of the first ALPN value. h2 stays h2; http/1.1 becomes h1; no ALPN is 00 |
So t13d1516h2 is: TLS over TCP, TLS 1.3, connecting to a domain name, offering 15 cipher suites and 16 extensions, negotiating HTTP/2. You can read that much without a lookup table, which is the point — JA3 gave you a bare MD5 and nothing else.
Segments b and c
Both are the first 12 hex characters of a SHA-256. Segment b covers the cipher suites: GREASE values dropped, the remainder sorted ascending, written as four-digit hex and joined with commas.
002f,0035,009c,009d,1301,1302,1303,c02b,c02c,c02f,c030,cca8,cca9
→ sha256, first 12 hex chars → 8daaf6152771Segment c covers the extensions, with three deletions: GREASE, SNI (0x0000) and ALPN (0x0010). SNI is removed because it varies with the site you are visiting rather than with your client, and ALPN because it is already spelled out in segment a. What is left is sorted, then the signature algorithms are appended after an underscore — in the order they were sent, not sorted, because that order is itself characteristic.
0005,000a,000b,000d,0012,0017,001b,0023,002b,002d,0033,44cd,ff01
_0403,0804,0401,0503,0805,0501,0806,0601
→ sha256, first 12 hex chars → e5627efa2ab1Why sorting matters
In 2023 Chrome started permuting its TLS extension order on every connection, deliberately, to stop the ecosystem from depending on it. JA3 hashes extensions in the order sent, so a single Chrome install began producing a different JA3 every time — useless as an identifier and actively harmful as a blocklist entry.
JA4 sorts before hashing, so the permutation cancels out and the same browser yields the same fingerprint. The cost is that JA4 cannot see ordering differences that are genuinely characteristic; the raw form below is there for when you need them.
The raw form
Hashes are only useful for equality. When two clients differ and you need to know where, ask for the unhashed variant — /api/ja4/raw returns segment a unchanged with b and c expanded back into their lists, so a diff points at the cipher or extension that actually moved.
curl -s https://kittens.sh/api/ja4/rawWhat it does and does not tell you
It identifies a TLS stack and its configuration — Chrome’s BoringSSL with Chrome’s settings, Go’s crypto/tls, Python over OpenSSL. It does not identify a person, a machine or a browser profile, and two different applications built on the same library with the same defaults will collide.
It is also not a secret. Anything that controls its own handshake can choose what to send, which is what impersonation libraries do. A matching JA4 is evidence that a client is what it claims, not proof. Its real strength is the negative case: a client whose JA4 says one thing while its User-Agent says another has told you something it did not mean to.
Licensing
JA4 itself is BSD-3-Clause. The rest of the JA4+ suite — JA4S, JA4H, JA4L, JA4X and the others — is under the FoxIO License 1.1, which does not permit monetisation without an OEM licence.
See your own
The inspector shows your JA4 with every field it was built from, in wire order. Or curl -s https://kittens.sh/api/ja4 from whatever client you want to measure. Next: JA3 and the Akamai HTTP/2 fingerprint.