Mismatching JA3 when comparing multiple implementations
When testing with this plugin, I get JA3s that don't match other implementations. Here's a PCAP of my testing (against latest master in docker): ja3-test.pcap.tgz.
The output from this plugin:
2023-11-02T18:26:33+00:00
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36
772,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-17513-11-45-51-18-65281-10-35-27-5-23-16-43-13-21,29-23-24,
efc7fcf303f23e80cbfcec938522f671
The output above is clearly missing the formats field of EC.
Analysing the pcap in Wireshark gives me a hash of 4ab55dd80cd12bd8221f0afe9feecf50 from the JA3 771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-17513-11-45-51-18-65281-10-35-27-5-23-16-43-13-21,29-23-24,0
I also get different results when I compare hashes when testing with curl compared to https://check.ja3.zone/ and https://tls.browserleaks.com/tls
There is two differences:
771, 4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-17513-11-45-51-18-65281-10-35-27-5-23-16-43-13-21,29-23-24, 0
-
Wireshark and others use Handshake version instead of actual TLS connection version, but this is constant (for backward compatibility reasons) it will be always 771 even using TLS 1.3
0x0303 is 771
-
EC point format, nginx-ssl-ja3 parses 0 as empty, others use 0
So you can normalize this yourself if you need:
- If first chunk is >771, use 771
- If last chunk is empty, use 0
👀
- ja3->version = SSL_version(ssl);
+ ja3->version = SSL_client_version(ssl);