用語集

TLSフィンガープリント(JA3 / JA4)とは何か?

TLSフィンガープリントは、クライアントのTLSハンドシェイクの特定の構造(暗号リスト、拡張機能、ALPN値、GREASEバイトなど)から導出されたハッシュであり、アプリケーション層のデータが交換される前に、基盤となるHTTPクライアント、ブラウザ、またはライブラリを識別します。

JA3とJA4の仕組み、スクレイパーがHTTPリクエストを送信する前にPythonのrequestsやcurlの使用が検出される理由、およびそれを無効化する方法を理解する。

解説

クライアントが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)のバリアントもあります。サーバーはフィンガープリントを計算し、許可/拒否リストと照合するか、他のシグナルとともにリスクスコアリングモデルに入力します。

JA3

オリジナルのTLS ClientHelloフィンガープリント。順序付けされた暗号/拡張/曲線/フォーマットフィールドのMD5。広く普及していますが、最新のブラウザにおける拡張順序のランダム化に対して脆弱です。

JA3S

JA3のサーバーサイド版で、TLS ServerHelloをフィンガープリントします。クライアントではなく、サーバーソフトウェアスタックを識別するために使用されます。

JA4

JA3の現代的な後継。GREASE、ランダム化、拡張機能の順序をより堅牢に処理します。JA4(TCP)、JA4Q(QUIC)、JA4H(HTTP)、JA4L(レイテンシ)、JA4T(TCPフィンガープリント)、JA4X(X.509証明書)に分割されます。

Akamai BMP / Datadome / Cloudflare bot.management

JA3/JA4をベースに、追加シグナル(TLS拡張順序ランダム化の癖、GREASEバイト検査、パケットタイミング)を組み合わせた独自のアンチボットフィンガープリント。実際のブラウザを使用しない限り、偽装は事実上不可能。

主な使用事例

HTTP レイヤーより前の段階で HTTP クライアント(curl、requests、Python http.client)を識別する
TLS層でのボット防御
ネットワークフォレンジックおよび IDS ルール
クライアントタイプ別のレート制限
カスタムまたは改造されたスクレイピングクライアントの検出
FAQ

よくある質問

よくある質問: tlsフィンガープリント.

User-Agent はクライアントが平文で送信するHTTP ヘッダーであり、任意の値に設定できます。JA3はTLS ハンドシェイク自体の構造から計算されるため、ヘッダーを設定するだけでは変更できません。JA3を変更するには、基盤となるTLS クライアントライブラリまたはその設定を変更する必要があります。

TLSフィンガープリントの不一致の可能性。Pythonの`requests`はurllib3のTLSスタックを使用しており、ChromeとはJA3/JA4が一致しないフィンガープリントを生成する。User-AgentにChromeと記載されていても、CloudflareはこれをChromeと一致しないとして検出する。`curl_cffi`(ChromeのTLSを模倣する)を使用するか、Playwright/Puppeteerで実際のブラウザを実行して修正する。

実際のChrome / Edge / Firefox / Safariはそれぞれ固有のJA3を持ち(ナイーブなブロックリストを回避するためにわずかにランダム化します)。curl、wget、Python requests、GoのNet/http、NodeのHTTPS、OkHttp、Java HttpClientなど数十のツールはそれぞれ識別可能な固有のJA3を持っています。これらをカタログ化した公開データベース(ja3er.com、abuse.ch)も存在します。

Pythonの`curl_cffi`、Goの`cycletls`、Go/Pythonの`tls-client`などTLSインパーソネーション対応HTTPクライアントを使用するか、Playwright/PuppeteerでリアルなChromiumブラウザを実行してください。これらのライブラリはChromeの正確なClientHello構造を再現するため、JA3/JA4がChromeと一致し、スクリプトであることが露呈しません。

モダンなChromeはすでに(GREASE拡張機能を通じて)ClientHelloをランダム化し、キャッシュとフィンガープリントを困難にしています。JA4はこれに対応するよう設計されています。クライアント側での単純なランダム化は、多くの場合、識別をより困難にするのではなく、より容易にします。なぜなら、その結果は実際のブラウザとは異なるからです。代わりに実際のブラウザのJA3に合わせてください。

間接的にはそうです。プロキシはTLSフィンガープリントを変更しません。クライアントは引き続き宛先とエンドツーエンドでTLSハンドシェイクを行います。ただし、レジデンシャルIPはベースラインの疑惑を軽減するため、レジデンシャルIPからの非Chrome JA3はアンチボットシステムに許容されることがある一方、データセンターIPからの同じJA3は即座にブロックされます。それでも、両方のレイヤーを修正することが正しい対応です。