Demystifying JA3: One Handshake at a Time

Ravi Teja
8 min readJan 22, 2022

Recently, I was browsing a website with BurpSuite and found out that the website was blocking my requests. In the pursuit of unlocking the mystery of how, I have stumbled across an incredible TLS fingerprinting technique called JA3.


Fingerprinting clients and blocking them based on a particular set of rules is not new. Many companies do have intelligent ways of Fingerprinting clients(one reason being to detect bots and malicious traffic) by using a cookie to track a user uniquely. After Snowden’s leak back in 2013, many websites started to adopt the HTTPS version by default. Many applications like malware, IoT devices also use TLS to connect securely to the Server. Thus, the popularity and widespread of the TLS protocol led to research and discovery of newer ways to fingerprint users uniquely.

How do HTTPS Connections work?

HTTPS in short is combination of two things:

  • TCP(Transmission Control Protocol) — 3 Way Handshake
  • TLS (Transport Layer Security)Client — Server Negotiation

TCP Handshake, also known as a 3 Way handshake, is a process in which the Client and Server establish a TCP Session. The following diagram illustrates how a TCP Connection is established.

TCP 3 - Way Hand Shake

TCP 3 Way Handshake

  • The client sends SYN (Synchronise Sequence Number), intimating the Server to start communication.
  • The Server sends SYN-ACK (Acknowledgement)set. ACK — stating that the Signal has been received and SYN to Sequence No it has to start the next segment with
  • The client responds with ACK packet acting as Acknowledgement, and thus further communication proceeds.

This happens in Layer 4 of the OSI Model.

TLS Client — Server Negotiation

TLS Handshake is a series of steps in which the Client and Server agree on a Cryptographic Algorithm, Version of Protocol and authenticate each other by exchanging and validating keys. This process can be self-explained as follows:

TLS Handshake process — Source

Note that this process happens in the Session Layer(Layer 5) of the OSI Model

Origin of TLS Fingerprinting

Early TLS Fingerprinting research comes from leE Brotherston blog, and later on, engineer’s at Salesforce John Althouse ,Jeff Atkinson, Josh Atkins improvised and created JA3 and JA3S. JA3 can be considered a modern-day User-Agent, which was used previously to track users over an HTTP connection.


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

JA3s and JARM

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


Thus during my exploration, I have found that the website I have visited using my BurpSuite might be using JA3 fingerprinting mechanism to uniquely identify and block TLS traffic coming from BurpSuite. You can use OWASP ZAP(which sends the Browser’s fingerprint to server) on top of BurpSuite or additionally proxy your traffic through some of the proxies as discussed above to bypass JA3 restrictions put by the WAF.

Further Exploration:

Things that are to be further explored are:

Update: JA4+ Algorithm has been released and you can check it out here —


Please visit my original blog link here for a list of exhaustive Resources/References used to write this blog post.

Please follow me on Twitter for more such Interesting Blogs —