Skip to main content
Experimental Crate: codec

seleniumbase_rs_codec::ja3 parses and renders JA3 strings with GREASE removed, so that a custom JA3 can be checked and replayed. JA3 is the Salesforce TLS client fingerprint: five comma-separated fields (handshake version, cipher suites, extensions, supported groups, point formats), each a dash-separated list of decimal ids, hashed with MD5. The MD5 here is a small pure function because JA3 is defined with it; nothing in the crate uses it for security. The submodule ja3::peetprint holds the sibling format that also records signature algorithms.

Tip

Chrome shuffles its TLS extensions on every connection, so its JA3 changes from one connection to the next by design. Compare JA4 when you compare a browser with a client (JA4).

The two strings and their hashes are those the capture tool recorded for the first hello of chrome-155-macos.json (under capture.tls.samples).

Ja3#

struct

A JA3 fingerprint: the five fields, GREASE removed, in wire order. It implements Display (the JA3 string) and FromStr (as Ja3::parse).

versionu16#

The handshake client_version (771 for TLS 1.2 and 1.3 clients).

ciphersVec<u16>#

Cipher suite ids.

extensionsVec<u16>#

Extension ids, in the order the client sent them.

groupsVec<u16>#

Supported group ids.

point_formatsVec<u8>#

EC point format ids.

Ja3::of#

method

The JA3 of a parsed hello: GREASE removed everywhere, extensions in wire order.

Ja3::parse#

method

Parses a JA3 string such as 771,4865-4866,0-23,29-23,0. Surrounding whitespace is trimmed. GREASE ids in the input are dropped, as the fingerprint is defined without them. The version and the ciphers must be present; the other lists may be empty. Numbers are plain ASCII digits: signs and spaces are refused.

text&strrequired#

At most MAX_JA3_LEN (16 KiB).

returnsResult<Ja3, Ja3Error>#

A Ja3Error naming the field and the token when the text is not a JA3 string.

Ja3::hash#

method

The lowercase hex MD5 of the JA3 string, the form JA3 databases list.

Ja3Field#

enum

One of the five fields of a JA3 string, named in errors. Its Display is version, ciphers, extensions, groups and point formats.

Ja3Error#

enum
Ja3Errorenum#

hex_lower, md5_hex#

fn

Lowercase hex encoding of bytes, and the lowercase hex MD5 of data. MD5 is broken as a hash: it is here only because JA3 and the peetprint hash are defined with it. Do not use it for anything that needs collision resistance.

Peetprint#

struct

A JA3-like TLS fingerprint that also records signature algorithms, in the format of a public TLS inspection service, read from its description: eight fields joined by |, each a - separated list. They are the supported versions, the ALPN protocols (written 1.0, 1.1, 2, or x and the hex of any other name), the supported groups, the signature algorithms, the PSK key exchange modes, the certificate compression algorithms, the cipher suites and the extensions. GREASE ids are written as the word GREASE. It implements Display and FromStr.

versions, groups, signature_algorithms, ciphersVec<Slot>#

As sent, GREASE kept as Slot::Grease.

alpnVec<String>#

ALPN protocol names (h2, http/1.1, …) as sent.

psk_modesVec<u8>#

PSK key exchange modes as sent.

cert_compressionVec<u16>#

Certificate compression algorithms as sent.

extensionsVec<Slot>#

The extensions. Peetprint::of sorts them; parsing keeps the given order.

Peetprint methods#

method
  • of: the peetprint of a parsed hello, normalized.
  • normalized: the same peetprint with the extension list sorted by the text of each token. The public description says only that the list is sorted; parsing accepts any order, and the spec layer compares extension lists as sets, so the sort rule never decides whether a custom peetprint is accepted.
  • extension_ids: the extension ids without GREASE, in the stored order.
  • hash: the lowercase hex MD5 of the string, the peetprint hash.
  • parse: reads a string of at most MAX_PEETPRINT_LEN (16 KiB), trimmed; a PeetprintError names the field and the token that failed.

Slot#

enum

A list entry of a peetprint: any GREASE value (RFC 8701), or a concrete id. Slot::from_id collapses a GREASE id into Slot::Grease.

slots, ids#

fn

In ja3::peetprint: the GREASE-collapsed slots of a list of wire ids, and the concrete ids of a slot list with GREASE dropped.

PeetField#

enum

One of the eight fields of a peetprint, named in errors. Its Display is versions, alpn, groups, signature algorithms, psk modes, certificate compression, ciphers and extensions.

PeetprintError#

enum
PeetprintErrorenum#

Constants#

const

The longest JA3 string Ja3::parse reads, and the longest peetprint Peetprint::parse reads.