解説
クライアントがTLS接続を開くと、最初のバイトはClientHelloパケットであり、クライアントがサポートする暗号スイート、TLSバージョン、拡張機能、楕円曲線、ALPN値を記述しています。これらの属性の正確なリストと順序は実装ごとに異なります。ChromeのClientHelloはFirefoxのものと異なり、curlのものと異なり、Pythonの`requests`ライブラリのものと異なります。
JA3(およびその後継であるJA4)は、ClientHelloの構造を短い識別子に変換するハッシュ形式です。アンチボットベンダーはすべての受信TLS接続に対してこのハッシュを計算し、既知のシグネチャと照合します。スクレイパーがPythonの`requests`を使用している場合、TLSフィンガープリントはOpenSSLのデフォルトと一致し、HTTPバイトを1つも送信する前から「本物のブラウザではない」として即座に識別されます。
これが、IPとUser-Agentが正しく見えても、多くのスクレイパーがCloudflare、Akamai、および類似のスタックで失敗する理由です。TLSレイヤーが、リクエストがChromeから来ていないことを明らかにしてしまいます。現代のステルスライブラリ(`curl_cffi`、`tls-client`、適切な起動フラグを持つPlaywrightなど)は、これを回避するために本物のブラウザのTLSフィンガープリントを模倣します。
仕組み
JA3はClientHelloの5つのフィールド(TLSバージョン、サポートされている暗号スイート、サポートされている拡張機能、サポートされている楕円曲線、サポートされている楕円曲線ポイント形式)からフィンガープリントを構築します。それらを結合し、結果をMD5ハッシュ化して、32文字のシグネチャを生成します。
JA4(現代の後継)はALPN、バージョン、SNIの有無、GREASEの処理を加え、ランダム化に対して耐性のある安定した方法で拡張機能を順序付けます。JA4にはQUIC(JA4Q)、HTTP(JA4H)、SSLセッション(JA4S)のバリアントもあります。サーバーはフィンガープリントを計算し、許可/拒否リストと照合するか、他のシグナルとともにリスクスコアリングモデルに入力します。