Demystifying JA3: One Handshake at a Time

2022-1-22 16:9:31 Author: 阅读量:11 收藏

JA3 is a fingerprinting mechanism performed on a Client that uses TLS to connect with the Server. This is done by performing a series of operations on the ClientHello packet received in the first step of the TLS Negotiation processes.

Earlier, many websites used to fingerprint users based on the User-Agent. In recent time’s it has taken seconds to impersonate that, and JA3 fingerprint is a significantly less known fingerprint solution used by many companies like Cloudflare in their bot management tools.

How JA3 is calculated?

Let’s explore the ClientHello packet first to understand how JA3 is calculated:

According to RFC5246 of TLSv1.2, ClientHello Packet is defined as

struct {
ProtocolVersion client_version;
Random random;
SessionID session_id;
CipherSuite cipher_suites<2..2^16-2>;
CompressionMethod compression_methods<1..2^8-1>;
select (extensions_present) {
case false:
struct {};
case true:
Extension extensions<0..2^16-1>;
} ClientHello;


  • client_version — Highest TLS Protocol Version supported by the client
  • random — A client generated random structure.
  • session_id — The ID of a session the client wishes to use for this connection.
  • cipher_suites — List of Cryptographic options supported by the client with the client’s first preference first.
  • compression_methods — List of the compression methods supported by the client, sorted by client preference.
  • extensions —This is an optional field that the client may request extended for functionality.

The extensions field can have EllipticCurve,EllipticCurvePointFormat as defined in RFC4492. Thus taking all of these things into consideration, we can have more than 2 quintillion ways of sending a ClientHello Message as

CipherPermutations = 20!
ExtensionPermutations = 15!
CurvePermutations = 4!
CurveFormatPermutations = 3!
TotalPermutations = 20! + 15! + 4! + 3! = 2432903315851008030

unique way’s to individually identify and fingerprint clients.

JA3 is calculated using the following 5 parameters taken from the ClientHello Packet as defined above:


JA3 gathers the decimal values of the bytes for the following fields in the Client Hello packet; SSL Version, Accepted Ciphers, List of Extensions, Elliptic Curves, and Elliptic Curve Formats. It then concatenates those values together in order, using a “,” to delimit each field and a “-” to delimit each value in each field.

With TLS 1.2 upgrade, RFC4492 was revised to RFC8422, and the EllipticCurve field was further referred to as supported_groups, so we use that field from the Wireshark packet to calculate JA3.

JA3 Calculation Steps from a TLS ClientHello Packet

JA3 Calculation steps from a TLS ClientHello Packet

GREASE(Generate Random Extensions And Sustain Extensibility) is a technique defined by this IETF Draft introduced by Google to prevent extensibility failures in the TLS ecosystem. It introduces invalid random values in the ClientHello packet with no effect and ensures that all the newly written code handles unexpected values. For the calculation of the JA3 fingerprint, we ignore this.

BurpSuite!? Two Fingerprints?

While further investigating, I have found that BurpSuite has got two fingerprints as follows:

  • First Packet — 2d5bd942ebf308df61e1572861d146f6 (771,4866–4865–4867–49196–49195–52393–49200–52392–49199–159–52394–163–158–162–49188–49192–49187–49191–107–106–103–64–49198–49202–49197–49201–49190–49194–49189–49193–49162–49172–49161–49171–57–56–51–50–49157–49167–49156–49166–157–156–61–60–53–47–49160–49170–22–19–49155–49165–10–255,0–5–10–11–13–50–16–17–23–35–43–45–51,29–23–24–25–30–256–257–258–259–260,0).
  • Next Consecutive Packets — eb5fdc72f0a76657dc6ea233190c4e1c (771,4866–4865–4867–49196–49195–52393–49200–52392–49199–159–52394–163–158–162–49188–49192–49187–49191–107–106–103–64–49198–49202–49197–49201–49190–49194–49189–49193–49162–49172–49161–49171–57–56–51–50–49157–49167–49156–49166–157–156–61–60–53–47–49160–49170–22–19–49155–49165–10–255,0–5–10–11–13–50–17–23–35–43–45–51,29–23–24–25–30–256–257–258–259–260,0).

Here is the actual difference of the packets from Wireshark(Extensions filed part of the ClientHello packet)

Difference of two packets sent by BurpSuite

In the first packet, we can observe an additional field called application_layer_protocol_negotiation as defined in RFC7301. It contains a list of protocols id’s supported by the client.

As defined in RFC7301:

When multiple application protocols are supported on a single server-
side port number, such as port 443, the client and the server need to
negotiate an application protocol for use with each connection. It
is desirable to accomplish this negotiation without adding network
round-trips between the client and the server, as each round-trip
will degrade an end-user’s experience. Further, it would be
advantageous to allow certificate selection based on the negotiated
application protocol

Due to this, two JA3 fingerprints were generated for BurpSuite, unlike any other browser which actually sends application_layer_protocol_negotiation in every packet. Why? Probably need to ask the creators of BurpSuite. — This website should not be used to find your JA3 fingerprint since it gives a false JA3 value as outlined in this Github Issue and this tweet. To give you an idea, you can check differences as shown below:

Difference in JA3 fingerprints generated by

The packet which we receive as a response from the ClientHello packet sent by the client is the ServerHello packet, and this can be used to calculate the unique fingerprint using the following fields of the ServerHello message:



md5(769,47,65281–0–11–35–5–16) = 4835b19f14997673071435cb321f5445

The Servers will respond to different clients differently, they will always respond to the same client the same.

Until now, JA3 and JA3s were more passive fingerprinting ways to detect, but the more active ones would be JARM.

In JARM, we send 10 Specially crafted TLS packets to get the most unique responses of the Server with varying protocol versions and ciphers. Further, the JARM fingerprint hash is a hybrid fuzzy hash; it uses a combination of a reversible and non-reversible hash algorithm to produce a 62 character fingerprint, unlike using MD5 as in JA3, JA3S case. You can read further about JARM on it here.

You can search for Server’s over the internet using the JARM fingerprint to essentially find things like C&C servers used by specific malware using the following engine’s:

Implications and Applications

JA3 and JA3s use MD5 hash to fingerprint the packet, unlike fuzzy hashing used by JARM to fingerprint the client from where the request is being sent. Using MD5 has some security implications like a Hash collision, but the authors have used MD5 to support old clients and advise logging the whole string(string before the MD5 hashing is done) for further analysis. Also, in some cases, some browsers can have the same JA3 fingerprints making them tough to identify. Still, the order of cipher’s supported by the browsers changed with every release in recent times, thus making it easy to fingerprint.

Further, with the introduction of ECH — Encrypted Client Hello, this fingerprinting can only be performed after decrypting the packet on the server-side rather than being fingerprinted by every entity involved in the transfer of the packet in clear text from Client to Server.

Some of the exciting applications of this could be as follows:

  • Redirect endpoint-specific traffic based on the JA3 fingerprint and only allow particular JA3 fingerprints by extending this project.
  • Block Bot’s, DDOS Traffic(Cloudflare does that) and in some cases Tor Connections as well.
  • JA3 is extensively used to fingerprint, and track-down Malware C&C . contains signatures of Malicious JA3 fingerprints for Blue Team to block these fingerprints within their network.
  • WAF to Block BurpSuite traffic to prevent getting hacked :D(In my case)

Meme depicting WAF’s blocking JA3 fingerprints of BurpSuite for not getting hacked

As said, “Nothing is Hack Proof,” yes you can also impersonate the JA3 fingerprints sent by your TLS Application as explained by CU Cyber in their using a tool called ja3transport or using another project called CycleTLS