JA4+ network fingerprinting library for TLS, TCP, HTTP, SSH, and X.509 analysis
Project description
JA4+
A Python library for JA4+ network fingerprinting. Implements all eight JA4+ methods for identifying and classifying network traffic based on TLS, TCP, HTTP, SSH, and X.509 characteristics.
JA4+ is a set of network fingerprinting standards created by FoxIO. This library is an independent Python implementation of the published specification. For the original spec, see the FoxIO JA4+ repository.
Supported Fingerprint Types
| Type | Protocol | Description |
|---|---|---|
| JA4 | TLS | Client fingerprint from ClientHello messages |
| JA4S | TLS | Server fingerprint from ServerHello messages |
| JA4H | HTTP | Client fingerprint from request headers and cookies |
| JA4T | TCP | Client OS fingerprint from SYN packets |
| JA4TS | TCP | Server fingerprint from SYN-ACK packets |
| JA4L | TCP | Light distance and latency estimation |
| JA4X | X.509 | Certificate structure fingerprint from OID sequences |
| JA4SSH | SSH | Session type classification from traffic patterns |
Installation
pip install ja4plus
Or install from source:
git clone https://github.com/Crank-Git/ja4plus.git
cd ja4plus
pip install -e .
Licensing
This library (ja4plus) is released under the BSD 3-Clause License.
The JA4+ fingerprinting specifications were created by FoxIO:
- JA4 (TLS Client Fingerprinting) is open source under BSD-3-Clause per FoxIO.
- JA4S, JA4H, JA4T, JA4TS, JA4L, JA4X, JA4SSH implement FoxIO's specifications and are subject to the FoxIO License 1.1.
The FoxIO License 1.1 is permissive for most use cases, including academic use, internal business use, and security research. Commercial productization or resale of these fingerprinting methods (other than JA4) may require a separate license from FoxIO.
See the FoxIO License for full terms, and LICENSE in this repository for the complete dual-license notice.
Quick Start
from scapy.all import rdpcap
from ja4plus import JA4Fingerprinter
packets = rdpcap("capture.pcap")
fp = JA4Fingerprinter()
for packet in packets:
result = fp.process_packet(packet)
if result:
print(f"JA4: {result}")
Usage
Class-Based API
Each fingerprinter processes packets and collects results:
from ja4plus import JA4Fingerprinter, JA4SFingerprinter, JA4TFingerprinter
ja4 = JA4Fingerprinter()
ja4s = JA4SFingerprinter()
ja4t = JA4TFingerprinter()
for packet in packets:
ja4.process_packet(packet)
ja4s.process_packet(packet)
ja4t.process_packet(packet)
for entry in ja4.get_fingerprints():
print(entry["fingerprint"])
Function-Based API
For one-shot fingerprinting of individual packets:
from ja4plus import generate_ja4, generate_ja4s, generate_ja4h
fingerprint = generate_ja4(packet)
All Fingerprinters
from ja4plus import (
JA4Fingerprinter, # TLS Client
JA4SFingerprinter, # TLS Server
JA4HFingerprinter, # HTTP
JA4TFingerprinter, # TCP Client (SYN)
JA4TSFingerprinter, # TCP Server (SYN-ACK)
JA4LFingerprinter, # Latency
JA4XFingerprinter, # X.509 Certificate
JA4SSHFingerprinter, # SSH
)
All fingerprinters share a common interface:
| Method | Description |
|---|---|
process_packet(pkt) |
Process a packet, returns fingerprint string or None |
get_fingerprints() |
Returns list of all collected fingerprint dicts |
reset() |
Clears all collected state |
See docs/usage.md for detailed usage of each fingerprinter.
Fingerprint Formats
| Type | Format | Example |
|---|---|---|
| JA4 | {proto}{ver}{sni}{ciphcnt}{extcnt}{alpn}_{hash}_{hash} |
t13d1516h2_8daaf6152771_e5627efa2ab1 |
| JA4S | {proto}{ver}{extcnt}{alpn}_{cipher}_{hash} |
t130200_1301_a56c5b993250 |
| JA4H | {method}{ver}{cookie}{ref}{cnt}{lang}_{hash}_{hash}_{hash} |
ge11cr0800_edb4461d7a83_4817af47a558_... |
| JA4T | {window}_{options}_{mss}_{wscale} |
65535_2-4-8-1-3_1460_7 |
| JA4TS | {window}_{options}_{mss}_{wscale} |
14600_2-4-8-1-3_1460_0 |
| JA4L | {latency_us}_{ttl} |
2500_56 |
| JA4X | {issuer_hash}_{subject_hash}_{ext_hash} |
a37f49ba31e2_a37f49ba31e2_dd4f1a0ef8b2 |
| JA4SSH | c{mode}s{mode}_c{pkts}s{pkts}_c{acks}s{acks} |
c36s36_c51s80_c69s0 |
Requirements
- Python 3.8+
- scapy >= 2.4.0
- cryptography >= 3.4.0
Development
git clone https://github.com/Crank-Git/ja4plus.git
cd ja4plus
pip install -e ".[dev]"
pytest tests/ -v
Spec Validation
ja4plus is validated against FoxIO's official test vectors. Run the validation suite:
python tests/download_test_vectors.py
pytest -m spec_validation -v
License
BSD 3-Clause License. See LICENSE for details.
Acknowledgments
JA4+ was created by John Althouse at FoxIO. This library is an independent implementation of the published specification. For the original spec and reference implementation, see github.com/FoxIO-LLC/ja4.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ja4plus-0.3.0.tar.gz.
File metadata
- Download URL: ja4plus-0.3.0.tar.gz
- Upload date:
- Size: 6.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db05c5f5ad535f7d9db68eae9aecc84b05ede53c79fb6f65c6e3bf3c7ae64699
|
|
| MD5 |
6e6fd8a3ab7a542f0c993ac2bcb9aeef
|
|
| BLAKE2b-256 |
8e3754b5b465bc791e873805bba4434bada7e97483aef3a14c1c4e9cdefd7f5b
|
Provenance
The following attestation bundles were made for ja4plus-0.3.0.tar.gz:
Publisher:
publish.yml on Crank-Git/ja4plus
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ja4plus-0.3.0.tar.gz -
Subject digest:
db05c5f5ad535f7d9db68eae9aecc84b05ede53c79fb6f65c6e3bf3c7ae64699 - Sigstore transparency entry: 1181746023
- Sigstore integration time:
-
Permalink:
Crank-Git/ja4plus@8301a8c286eb4bc27e982cc2cae4001b5740bedb -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/Crank-Git
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8301a8c286eb4bc27e982cc2cae4001b5740bedb -
Trigger Event:
release
-
Statement type:
File details
Details for the file ja4plus-0.3.0-py3-none-any.whl.
File metadata
- Download URL: ja4plus-0.3.0-py3-none-any.whl
- Upload date:
- Size: 49.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0482f9c1db9ad0b9814de6efa0961c1a51c2162611f96a8ffe5aa612bc16f0a2
|
|
| MD5 |
d95b49793eae5fad5df3e163a485a628
|
|
| BLAKE2b-256 |
9305f59d8b37f1de3e5868633f895da6d74354a340d30e3de3bdac7f01d3be4d
|
Provenance
The following attestation bundles were made for ja4plus-0.3.0-py3-none-any.whl:
Publisher:
publish.yml on Crank-Git/ja4plus
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ja4plus-0.3.0-py3-none-any.whl -
Subject digest:
0482f9c1db9ad0b9814de6efa0961c1a51c2162611f96a8ffe5aa612bc16f0a2 - Sigstore transparency entry: 1181746025
- Sigstore integration time:
-
Permalink:
Crank-Git/ja4plus@8301a8c286eb4bc27e982cc2cae4001b5740bedb -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/Crank-Git
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8301a8c286eb4bc27e982cc2cae4001b5740bedb -
Trigger Event:
release
-
Statement type: