Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteJA3 and JA4 are fingerprints of a client’s TLS handshake. A scraping target can observe the ClientHello, turn its ordered fields into a JA3 or JA4 value, and use that value to group traffic or investigate anomalies. The fingerprint is useful evidence, not a standalone proof that a request is automated.
JA3 is an MD5 hash of five ordered ClientHello field groups after GREASE values are removed. JA4 keeps a readable transport/TLS/SNI/cipher/extension/ALPN prefix and adds normalized, truncated SHA-256 hashes. JA4 is designed for TLS over TCP and QUIC, so it remains informative as TLS 1.3 and HTTP/3 become common.
What a TLS fingerprint tells a scraping target
Before an HTTPS request carries HTTP headers, the client sends a TLS ClientHello. It advertises capabilities such as protocol version, cipher suites, extensions, elliptic curves, point formats and ALPN. A network sensor at the destination, reverse proxy or monitoring point can read that handshake and derive a compact fingerprint.
That value can be compared with later connections. Requests that share a fingerprint may come from the same client stack, while an unusual combination can be investigated alongside request timing, headers, cookies, HTTP version and navigation behavior. The fingerprint does not, by itself, prove that two connections belong to one person or that a request is a scraper.
#1 Best Overall
What it cannot tell you
- It is not the website URL, page content or an account identifier.
- It does not decrypt the HTTPS session.
- It is not a universal bot verdict. Browser versions, operating systems, TLS libraries, proxies and transport choices can produce different values, and unrelated clients can share one.
How JA3 is constructed
Salesforce’s JA3 method uses five ordered fields from the ClientHello:
- SSL/TLS version.
- Accepted cipher suites.
- Extensions.
- Elliptic curves.
- Elliptic-curve point formats.
Values inside each field are joined with hyphens; the five fields are joined with commas. GREASE values are removed before hashing. The resulting source string is MD5-hashed into a 32-character hexadecimal JA3 value. The ordering matters: changing the advertised order can change the source string and therefore the hash.
JA3 was invented at Salesforce in 2017. The Salesforce JA3 repository was archived on May 1, 2025, so existing deployments remain useful while newer TLS fingerprinting work is directed toward FoxIO’s JA4 family.
A small, runnable JA3 calculator
This Python function assumes that another parser has already extracted the five ClientHello fields. It applies the documented GREASE filtering, builds the source string and returns both the source and its hash.
import hashlib
GREASE = {
0x0a0a, 0x1a1a, 0x2a2a, 0x3a3a,
0x4a4a, 0x5a5a, 0x6a6a, 0x7a7a,
0x8a8a, 0x9a9a, 0xaaaa, 0xbaba,
0xcaca, 0xdada, 0xeaea, 0xfafa,
}
def without_grease(values):
return [value for value in values if value not in GREASE]
def ja3(version, ciphers, extensions, curves, point_formats):
fields = [
str(version),
"-".join(map(str, without_grease(ciphers))),
"-".join(map(str, without_grease(extensions))),
"-".join(map(str, without_grease(curves))),
"-".join(map(str, without_grease(point_formats))),
]
source = ",".join(fields)
return source, hashlib.md5(source.encode("ascii")).hexdigest()
source, fingerprint = ja3(
version=771,
ciphers=[4865, 4866, 0x0a0a, 4867],
extensions=[0, 11, 10, 0x1a1a, 16],
curves=[29, 23],
point_formats=[0],
)
print(source)
print(fingerprint)
The example values are only input data for demonstrating the calculation; they are not a claim about any particular browser. A production collector must parse the actual packet and preserve the capture time, transport and sensor version with the result.
What JA4 adds
FoxIO defines JA4 as TLS Client Fingerprinting. Its value has three underscore-separated sections. The first is readable: transport, TLS version, SNI presence, cipher count, extension count and a two-character marker derived from the first ALPN value. The next two sections are truncated SHA-256 hashes: one for a normalized cipher list, and one for normalized extensions plus signature algorithms. GREASE values are ignored.
For example, t13d1516h2_8daaf6152771_e5627efa2ab1 can be read as TLS over TCP (t), TLS 1.3 (13), SNI present (d in this example), 15 ciphers, 16 extensions and an h2 ALPN marker, followed by the two normalized hash sections.
Transport and protocol coverage
JA4 explicitly distinguishes TLS over TCP from QUIC and DTLS. The transport prefix uses t for TLS over TCP, q for QUIC and d for DTLS. Including ALPN and transport helps analysts retain signal when clients use HTTP/2 or HTTP/3 instead of HTTP/1.1.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchRank #2
JA4 and the wider JA4+ family
JA4 is one member of FoxIO’s JA4+ family. JA4H fingerprints HTTP clients rather than only the TLS handshake. The family also includes methods for server, X.509, TCP, SSH, DHCP and other protocols. JA4+ values use an a_b_c layout, allowing an analyst to hunt on selected sections as well as the complete value.
JA3 versus JA4
| Question | JA3 | JA4 |
|---|---|---|
| Output | A 32-character MD5 hash of the five-field source string. | A readable prefix plus two truncated SHA-256 sections. |
| Ordering changes | Because the source is ordered, reordering advertised values can change the hash. | Normalization makes the fingerprint less sensitive to ordering changes. |
| Transport | Commonly used for TLS ClientHello observations. | Explicitly labels TLS/TCP, QUIC or DTLS. |
| ALPN | Not represented as a readable component in the five-field JA3 source. | Includes a marker from the first ALPN value. |
| GREASE | Removed before the source is hashed. | Removed before normalized values are hashed. |
| HTTP-level detail | None; JA3 is TLS-only. | Use the separate JA4H method when HTTP request details are needed. |
| Deployment | Widely implemented in existing sensors and rules. | Newer FoxIO tooling; availability depends on the sensor and package version. |
Neither is categorically “better.” JA3 is valuable when your existing IDS, logs or historical baselines already use it. JA4 is generally easier to inspect, handles QUIC explicitly and offers normalization intended to preserve useful signal as modern TLS evolves. For an HTTP-behavior investigation, add JA4H rather than expecting a TLS fingerprint to answer an HTTP question.
Can a site detect your scraper from JA3 or JA4?
Yes. A receiving network edge or sensor can observe the ClientHello and match its JA3 or JA4 against known values or local baselines. Suricata documents JA3 and JA4 as rule buffers, including ja3.hash and ja3.string. Zeek’s package catalog lists a Salesforce JA3 package and an official FoxIO JA4 package for logging and analysis.
Detection becomes stronger when several independent signals agree:
- TLS or QUIC fingerprint and ALPN.
- HTTP version, headers, cookie handling and authorization behavior.
- Request spacing, concurrency, retries and navigation sequence.
- Whether images, scripts and redirects are fetched like a browser.
- Operational context such as source network, time window and account history.
A fingerprint should therefore be treated as a grouping and anomaly-analysis signal. The available technical descriptions do not establish a universal detection accuracy, false-positive rate or evasion success rate, so no honest guide can promise that changing one value will defeat anti-bot controls.
How to inspect fingerprints in your own traffic
Capture where the ClientHello is visible
Place the sensor at a point that sees the initial TLS or QUIC handshake: your controlled egress, a reverse proxy, a load balancer or a packet-monitoring segment. Capturing only decrypted application logs after termination will not reproduce the original client fingerprint unless the terminating device exports it.
Use Suricata
Enable the TLS JA3 and JA4 fingerprint options in suricata.yaml. The documented configuration keys are app-layer.protocols.tls.ja3-fingerprints and app-layer.protocols.tls.ja4-fingerprints. After traffic is processed, write rules or alerts against the JA3 buffers such as ja3.hash and ja3.string, and retain the event timestamp, source, destination and transport with each record.
Use Zeek
Install the Salesforce JA3 package or FoxIO JA4 package from Zeek’s package catalog, then export the resulting logs into the same timeline as HTTP and connection logs. Package and sensor versions matter: record them so a later implementation change is not mistaken for a client population change.
Rank #3
Use Wireshark or library implementations
Salesforce’s ecosystem includes JA3 scripts, while FoxIO publishes JA4 implementations and Wireshark-related tooling. These are useful for validating a sample capture and comparing the fields that produced a value. Keep the original capture or an approved metadata record; a hash alone is difficult to audit.
How to change or standardize a scraper’s fingerprint
You cannot safely “set a JA3 string” as an HTTP header. The value is generated by the TLS implementation from the ClientHello it actually sends. Changing the TLS library, cipher ordering, extension set, supported groups, ALPN, protocol version or transport can change the observed fingerprint. Browser automation, a native browser and a non-browser HTTP client may therefore produce different values even when they request the same URL.
- Define the client profile you intend to operate, such as a specific browser family and version or a controlled service client.
- Capture a representative ClientHello from that profile and calculate JA3 and JA4 with the same implementation used by your monitoring system.
- Check that ALPN, HTTP version, headers, cookies and navigation behavior are consistent with the profile. A browser-looking TLS value paired with an incompatible HTTP pattern is still anomalous.
- Version the TLS library, browser build, operating system image and fingerprinting implementation. Recalculate after upgrades.
- Use the result for compatibility testing and operational consistency, not as a promise of bypassing access controls.
If you need to investigate a mismatch, compare the complete field lists before comparing hashes. A changed JA3 can be explained by one extension or ordering difference; a changed JA4 may reflect transport, ALPN, counts or normalized lists.
Operational reliability, performance and cost considerations
Normalize consistently
Apply the same GREASE removal and JA4 normalization rules at every sensor. Otherwise identical clients can appear different simply because collectors disagree. Keep implementation and package versions beside the records.
Free tools Windows power users keep installed
One-click scans. No signup required.
Retain context, not just hashes
Store timestamp, transport, TLS version, SNI-presence state, ALPN, source context and the sensor version. This permits later comparison when a browser or library update changes its ClientHello.
Plan for QUIC
HTTP/3 uses QUIC, so a TCP-only collection point will miss part of the traffic or force an incomplete comparison. JA4’s transport prefix helps separate QUIC from TLS over TCP; make sure your chosen sensor actually observes both.
Estimate resources from your traffic
Fingerprinting cost depends on packet volume, retention period, rule count and whether you keep full captures. The supplied specifications do not establish a universal CPU, memory or storage benchmark. Measure your own sensor under representative traffic rather than applying a percentage from another deployment.
Common failure modes and fixes
No fingerprint appears
Cause: the sensor sees only post-termination HTTP logs, misses QUIC, or the capture starts after the ClientHello.
Fix: move collection to a point that sees the handshake, enable the relevant TLS and QUIC analyzers, and verify that the first packets are present.
Values differ between two sensors
Cause: different package versions, GREASE handling, normalization or parser behavior.
Fix: align implementations, record versions, compare the raw field lists and test both sensors against the same capture.
JA3 matches but behavior still looks automated
Cause: JA3 represents only the TLS ClientHello.
Fix: correlate HTTP headers, JA4H where appropriate, cookies, timing, concurrency and navigation order.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →JA4 changes after a client upgrade
Cause: the new build changed ciphers, extensions, signature algorithms, ALPN or transport.
Fix: create a new versioned baseline and document the upgrade instead of treating every new value as malicious.
A rule matches too broadly
Cause: a shared fingerprint is being used as an identity verdict.
Fix: combine the match with time, source, HTTP and account context, and review false positives before enforcement.
Recommended Free Tools
Best Value
Or skip the browser setup
If your goal is to obtain a clean visual record of a page rather than build a browser-and-capture pipeline, ScreenshotNeo provides a website screenshot API and MCP server. It does not change a target’s JA3 or JA4 and should not be treated as a fingerprint-evasion service; it removes capture plumbing from your application.
One GET request returns PNG, JPEG, WebP or PDF. This cURL example follows the documented API format:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for parameters and response headers. Equivalent Python and Node.js calls are:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Before capture, ScreenshotNeo can accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Only clean shots are billed. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, and each response reports the result through X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Other options include full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or a custom viewport, retina scale, PDF paper size/margins/landscape/page ranges, custom CSS and JavaScript, pre-capture clicks, selector hiding, waits for a selector/delay/network idle, request or resource blocking, custom headers/cookies/user agent/Authorization, timezone and geolocation, transparent backgrounds, resizing, chosen-TTL caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of 100 URLs per call, a usage API and an OpenAPI specification. Parameter names used by other screenshot APIs also work.
The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free, and every feature is available on every plan. Create a free ScreenshotNeo account to try it without a card.
Frequently Asked Questions
Is a JA3 or JA4 value reversible into the original ClientHello?
No. The published values are hashes or hash sections. Keep the parsed fields or an approved packet record if you need to explain why a value was produced.
Why can two connections from the same application have different fingerprints?
A browser or TLS library can vary by version, operating-system build, enabled features, ALPN choice or TCP-versus-QUIC transport. Compare those conditions before treating the difference as suspicious.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →When should I collect JA4H as well?
Collect JA4H when the question concerns HTTP-client behavior—such as request headers or HTTP-level grouping—because JA3 and JA4 describe the TLS-side ClientHello rather than the request itself.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




