Introduction
TLS fingerprinting is a passive network monitoring technique that identifies client applications and malware by analyzing the unique characteristics of their TLS handshakes. Every TLS client — whether it is Chrome, a Python script, or a malware command-and-control beacon — produces a distinctive fingerprint based on its supported cipher suites, TLS extensions, elliptic curves, and signature algorithms. By capturing and analyzing these fingerprints, security teams can detect unauthorized applications, identify malware families, and enforce network policy without decrypting traffic.
This guide compares three approaches to self-hosted TLS fingerprinting: JA3/JA4, the industry-standard fingerprinting libraries from Salesforce and FoxIO; Zeek with its built-in SSL analysis and JA3 plugin; and Suricata with TLS fingerprinting and signature-based detection. Each tool serves a different operational niche, from lightweight Python-based fingerprint generation to full-scale network security monitoring platforms.
JA3/JA4 Fingerprinting Libraries
JA3 (created by Salesforce) and JA4+ (created by FoxIO) are the de facto standards for TLS client fingerprinting. Both operate on the same principle: they compute a hash of the TLS Client Hello message parameters (cipher suites, extensions, elliptic curves, and elliptic curve point formats), producing a compact fingerprint string like 6734f37431670b3ab4292b8f60f29984.
How JA3 Works
JA3 concatenates five fields from the Client Hello into a string and computes its MD5 hash:
- TLS version
- Accepted cipher suites (in order)
- List of extensions (in order)
- Supported elliptic curves
- Elliptic curve point formats
The resulting 32-character MD5 hash is the JA3 fingerprint.
How JA4+ Differs
JA4+ improves on JA3 in several ways:
- SHA-256 instead of MD5 for collision resistance
- Multi-protocol support — JA4 (TLS client), JA4S (TLS server), JA4H (HTTP), JA4X (X.509), JA4SSH (SSH)
- Human-readable fingerprint format instead of raw hashes
- Better GREASE handling — correctly ignores GREASE values that Chrome inserts
- QUIC support — fingerprints for QUIC/HTTP3 handshakes
Python Installation and Usage
| |
JA3 Python example:
| |
JA4+ Python example:
| |
Docker Compose for Automated Fingerprinting
| |
Pros and Cons
- ✅ Lightweight — single Python library, minimal dependencies
- ✅ Industry standard — JA3/JA4 fingerprints are widely recognized
- ✅ Easy to integrate with existing Python tooling
- ❌ Library only — requires custom scripting for continuous monitoring
- ❌ No built-in UI, database, or alerting
- ❌ MD5-based JA3 has known hash collisions (fixed in JA4+)
Zeek SSL Analysis
Zeek (formerly Bro) is a powerful network security monitoring platform that passively analyzes network traffic and generates comprehensive logs. Its built-in SSL/TLS analyzer extracts detailed information from every TLS handshake, including JA3 fingerprints when the JA3 plugin is enabled.
Key Features
- Built-in SSL analyzer — extracts certificates, cipher suites, SNI, TLS versions
- JA3 plugin — computes JA3 and JA3S fingerprints for every connection
- Connection logging —
ssl.log,conn.log,x509.logfor comprehensive analysis - Scripting language — Zeek scripts for custom detection logic
- Integration ecosystem — feeds into Elasticsearch, Splunk, Kafka
Docker Compose Configuration
| |
Zeek SSL Analysis Configuration
In local.zeek, enable SSL logging and JA3 fingerprinting:
| |
Example query to find unique JA3 fingerprints in Zeek logs:
| |
Example output showing the most common TLS fingerprints on your network:
| |
Detection Script Example
Zeek can alert on suspicious TLS fingerprints:
| |
Pros and Cons
- ✅ Full network security monitoring platform — not just fingerprinting
- ✅ Comprehensive SSL/TLS logging with certificates, SNI, cipher details
- ✅ Powerful scripting language for custom detection rules
- ✅ Large community with shared threat intelligence scripts
- ❌ Heavier than JA3/JA4 library alone — requires continuous packet capture
- ❌ Steeper learning curve — Zeek scripting language has its own syntax
- ❌ No built-in web dashboard — needs external tools for visualization
Suricata TLS Fingerprinting
Suricata is a high-performance Network Intrusion Detection System (NIDS) that includes TLS fingerprinting as part of its deep packet inspection engine. Suricata can extract TLS metadata, compute JA3 fingerprints, and trigger alerts based on TLS characteristics using its signature language.
Key Features
- TLS logging — extracts SNI, cipher suites, TLS version, certificate details
- JA3 fingerprinting — built-in JA3 computation in the TLS parser
- Signature-based detection — write rules that trigger on specific TLS fingerprints
- High performance — multi-threaded, GPU-accelerated, runs at line rate
- EVE JSON output — structured JSON logs for ingestion into SIEM platforms
Docker Compose Configuration
| |
Suricata TLS Configuration
In suricata.yaml, enable TLS logging with JA3:
| |
Signature Rules for TLS Fingerprinting
Suricata signatures can match on TLS fingerprints and certificate details:
| |
Pros and Cons
- ✅ High-performance packet processing with multi-threading
- ✅ Signature language for precise detection rules
- ✅ Unified IDS/IPS — TLS fingerprinting alongside broader threat detection
- ✅ EVE JSON output for SIEM integration (Elasticsearch, Splunk)
- ❌ Signature syntax has a learning curve
- ❌ Rules require ongoing maintenance and tuning
- ❌ False positives if rules are too broad
Comparison Table
| Feature | JA3/JA4 Libraries | Zeek SSL Analysis | Suricata TLS |
|---|---|---|---|
| Stars | 3,102★ / 1,958★ | 7,200★+ | 6,300★+ |
| Type | Python libraries | Network monitoring platform | IDS/IPS platform |
| Fingerprint Method | JA3 (MD5) / JA4+ (SHA-256) | JA3 (via plugin) | JA3 (built-in) |
| Multi-Protocol | TLS only / TLS+HTTP+SSH+QUIC | TLS + many other protocols | TLS + many other protocols |
| Web Dashboard | None | External (ELK/Splunk) | External (EVE JSON) |
| Detection Engine | Manual (Python scripts) | Zeek scripts | Signature rules |
| Performance | N/A (library) | Good (single-threaded) | Excellent (multi-threaded) |
| Setup Complexity | Low (pip install) | Medium | Medium |
| Best For | Custom tooling, research | Security monitoring, forensics | Real-time IDS/IPS detection |
| Primary Language | Python | C++ / Zeek script | C |
Why Self-Host Your TLS Fingerprinting?
TLS fingerprinting provides visibility into encrypted traffic without breaking encryption — a capability that becomes increasingly critical as TLS 1.3 adoption approaches 95% of web traffic. By analyzing Client Hello fingerprints, security teams can detect unauthorized applications on the corporate network, identify malware command-and-control beacons using known malicious JA3 signatures, and enforce acceptable-use policies without deploying TLS interception proxies.
For organizations that already operate self-hosted network monitoring infrastructure, adding TLS fingerprinting is straightforward. Zeek and Suricata can be deployed on an existing monitoring server or virtual machine, passively tapping a mirror port on the network switch. The TLS analysis happens alongside other protocol analysis with minimal additional overhead. For broader network traffic analysis capabilities, see our network traffic analysis guide.
Compliance is another driver. Regulations like PCI DSS require visibility into encrypted traffic flows, and TLS fingerprinting provides that visibility without the privacy and performance concerns of full TLS decryption. By maintaining an inventory of TLS fingerprints on your network, you can demonstrate which applications are communicating, with what TLS parameters, and whether any deprecated cipher suites or TLS versions remain in use. For managing TLS certificates and PKI infrastructure, see our certificate lifecycle management guide. For securing your TLS termination endpoints, see our TLS termination proxy comparison guide.
FAQ
Can JA3/JA4 fingerprints be spoofed?
Yes. A sophisticated attacker can modify their TLS client to mimic a known browser fingerprint. However, this is non-trivial because the fingerprint depends on the TLS library’s internal behavior. Changing the cipher suite order or adding specific extensions requires modifying the TLS stack, which most commodity malware does not do. JA4+ adds additional entropy from the TLS state machine and HTTP headers, making spoofing harder. In practice, JA3/JA4 is a strong indicator, not a definitive identification mechanism — use it as one signal among many in your detection pipeline.
Does TLS 1.3 change fingerprinting?
TLS 1.3 simplifies the handshake significantly, which actually makes fingerprinting more reliable. With fewer variable fields in the Client Hello, the remaining fields (supported groups, signature algorithms, key share groups) become even more distinctive between different clients. JA4+ explicitly targets TLS 1.3 with its t13 prefix format. Both JA3 and JA4+ work correctly with TLS 1.3.
What is the difference between JA3 and JA3S?
JA3 fingerprints the TLS client (the initiator of the connection), while JA3S fingerprints the TLS server (based on the Server Hello message). Server fingerprints are less distinctive than client fingerprints because most servers respond with a single cipher suite and fewer extensions. However, JA3S can identify specific server software versions (e.g., Apache httpd 2.4.57 vs nginx 1.25.3) when their TLS configurations differ.
How do I build a database of known JA3 fingerprints?
Several community-maintained resources exist:
- JA3 Fingerprints (https://github.com/salesforce/ja3) — Salesforce’s reference implementation includes sample fingerprints
- SSL Blacklist (https://sslbl.abuse.ch/) — Abuse.ch maintains JA3 fingerprints for malware
- JA4+ Database (https://github.com/FoxIO-LLC/ja4) — FoxIO’s repository includes common fingerprints
For your own environment, run Zeek or Suricata for a week and collect all unique JA3 hashes with their associated SNI values. This gives you a baseline of normal TLS fingerprints for your network, making anomalies stand out.
Can I use TLS fingerprinting without deploying a full NIDS?
Yes. The JA3/JA4 Python libraries can be used with TShark or tcpdump to fingerprint traffic from pcap files. A lightweight approach is:
| |
This requires no persistent daemon — just periodic captures and analysis.
💰 Want to test your market judgment? I use Polymarket for prediction market trading — the world’s largest prediction market platform where you can bet on anything from election outcomes to tech regulation timelines. Unlike gambling, this is a real information market: the more you know, the better your odds. I’ve profited by predicting tech-related event trajectories. Sign up with my invite link: Polymarket.com