All fingerprinters inherit from BaseFingerprinter and share a common interface.
| Method | Returns | Description |
|---|---|---|
process_packet(packet) |
str or None |
Process a scapy packet. Returns fingerprint string if one is generated. |
get_fingerprints() |
list[dict] |
Returns all collected fingerprints as {"fingerprint": str, ...} dicts. |
reset() |
None |
Clears all collected fingerprints and internal state. |
TLS Client Hello fingerprinting.
from ja4plus import JA4Fingerprinter
fp = JA4Fingerprinter()
result = fp.process_packet(packet) # Returns JA4 string or None
raw = fp.get_raw_fingerprint(packet) # Returns unhashed fingerprintTLS Server Hello fingerprinting.
from ja4plus import JA4SFingerprinter
fp = JA4SFingerprinter()
result = fp.process_packet(packet)HTTP request fingerprinting.
from ja4plus import JA4HFingerprinter
fp = JA4HFingerprinter()
result = fp.process_packet(packet)TCP client fingerprinting from SYN packets.
from ja4plus import JA4TFingerprinter
fp = JA4TFingerprinter()
result = fp.process_packet(packet)TCP server fingerprinting from SYN-ACK packets.
from ja4plus import JA4TSFingerprinter
fp = JA4TSFingerprinter()
result = fp.process_packet(packet)Network latency estimation from TCP handshake timing.
from ja4plus import JA4LFingerprinter
fp = JA4LFingerprinter()
result = fp.process_packet(packet)X.509 certificate structure fingerprinting.
from ja4plus import JA4XFingerprinter
fp = JA4XFingerprinter()
result = fp.fingerprint_certificate(der_bytes) # From DER-encoded cert
result = fp.process_packet(packet) # From TLS packet
details = fp.get_cert_details(x509_cert) # Extract OID detailsSSH session classification.
from ja4plus import JA4SSHFingerprinter
fp = JA4SSHFingerprinter(packet_count=200)
result = fp.process_packet(packet)
info = fp.interpret_fingerprint(result) # Session type analysis
hassh = fp.get_hassh_fingerprints() # HASSH fingerprints
lookup = fp.lookup_hassh(hassh_value) # Known HASSH lookupOne-shot fingerprinting without maintaining state:
from ja4plus import (
generate_ja4,
generate_ja4s,
generate_ja4h,
generate_ja4t,
generate_ja4ts,
generate_ja4l,
generate_ja4x,
generate_ja4ssh,
)
# Each takes a scapy packet and returns a fingerprint string or None
result = generate_ja4(packet)| Function | Input | Description |
|---|---|---|
generate_ja4(packet) |
scapy packet | JA4 TLS client fingerprint |
generate_ja4s(packet) |
scapy packet | JA4S TLS server fingerprint |
generate_ja4h(packet) |
scapy packet | JA4H HTTP fingerprint |
generate_ja4t(packet) |
scapy packet | JA4T TCP client fingerprint |
generate_ja4ts(packet) |
scapy packet | JA4TS TCP server fingerprint |
generate_ja4l(packet) |
scapy packet | JA4L latency fingerprint |
generate_ja4x(cert_info) |
dict | JA4X certificate fingerprint (takes cert_info dict) |
generate_ja4ssh(packet) |
scapy packet | JA4SSH session fingerprint |
| Function | Description |
|---|---|
extract_tls_info(packet) |
Extract TLS handshake details from a packet |
is_grease_value(value) |
Check if a value is a GREASE value |
parse_client_hello(data) |
Parse raw ClientHello bytes |
parse_server_hello(data) |
Parse raw ServerHello bytes |
| Function | Description |
|---|---|
extract_http_info(packet) |
Extract HTTP request details from a packet |
is_http_request(data) |
Check if data is an HTTP request |
parse_http_request(data) |
Parse raw HTTP request bytes |
| Function | Description |
|---|---|
is_ssh_packet(data) |
Check if data is SSH traffic |
parse_ssh_packet(data) |
Parse SSH packet structure |
extract_hassh(data) |
Extract HASSH fingerprint from KEXINIT |
| Function | Description |
|---|---|
oid_to_hex(oid_string) |
Convert OID dotted string to ASN.1 hex encoding |
get_cert_details(cert) |
Extract issuer/subject RDNs and extensions from an x509 certificate |
extract_certificate_from_bytes(data) |
Find DER certificates in raw TLS record bytes |
extract_certificate_info(packet) |
Extract certificate details from a scapy packet |
Command-line interface for JA4+ fingerprinting. Installed as the ja4plus command.
ja4plus analyze <pcap_file> # Fingerprint a PCAP file
ja4plus live <interface> # Live capture (requires root)
ja4plus cert <cert_file> # Fingerprint an X.509 certificate| Option | Description |
|---|---|
--format table|json|csv |
Output format (default: table) |
--types ja4,ja4s,... |
Filter to specific fingerprint types |
--lookup |
Identify fingerprints using bundled ja4db database |
--version |
Print version |
Fingerprint identification using FoxIO's ja4plus-mapping.csv database.
from ja4plus.ja4db import JA4DBClient, lookup
# Module-level convenience function
result = lookup("t13d1516h2_8daaf6152771_02713d6af862")
# {"application": "Chromium Browser", "type": "ja4", "notes": ""}
# Or use the client for caching across multiple lookups
client = JA4DBClient()
result = client.lookup(fingerprint_string)| Class/Function | Description |
|---|---|
JA4DBClient() |
Client with local cache and bundled database |
JA4DBClient.lookup(fingerprint) |
Look up a fingerprint, returns dict or None |
lookup(fingerprint) |
Module-level convenience using a shared client |