指紋は新しい cookie
サードパーティ cookie は廃止されないまま、指紋識別が新たな追跡手段になった。訪問者のニックネームを算出するデモから始まり、指紋のデータ源、情報エントロピーが特徴をビットに換算する仕組み、そして Chrome、Safari、Tor がそれぞれ示す答えまでを追う。
日本語
コピー

このサイトでは、私が使っている手法であなたを特定することはできない。 JavaScript を無効にしているから、この指紋識別の技はそもそも動かない。だがネットワーク側の手段は今もあなたに有効だ。読み進めて、それが他の人たちに何をしたのかを見てほしい。
今日から、あなたをこう呼ぶ:
… computing…
ページを再読み込みしてみろ。cookie を消せ。VPN につなげ。
それでもあなたは … のままだ。
別の端末やスマホで開けば、ニックネームは変わる。だが同じくらい安定している。
シークレットモードなら違う? 上等だ。だが常に同じ? それは朗報じゃない。
想像してみろ:
あなたが訪れるほとんどのサイトは広告を出して稼ぎ、同時に私のスクリプトをこっそり動かして、あなたが例の … だと私に教えている。それを使ってどの広告を見せるか決められる。だがもっと重要なのは、あなたがそのサイトにアカウントを作っていれば、私はあなたのデータを買い取ると申し出られるということだ——彼らのプライバシーポリシーが共有を許していればの話だが:あなたの名前、行動履歴、AI との会話……
そう時間はかからない。私があなたについて知ることはあなたの友人より多くなる——おそらくあなた自身よりも。
「だから何?」——とあなたは言う。
「隠すものなんてないし。それに興味のある広告のほうがいい……たまにちょうど欲しいものを勧めてくれるし! そもそもデータは匿名化されてるんだろ……」
問題は、これがあなたの話ではまったくないということだ。そして今や広告の話でもない。誰もあなたのことなど気にしていない。だが警察や政府がたまたま気にしたなら、私は喜んで彼らから金を受け取る。
このデータの山を見ても、私には人間が見えない。見えるのはパターンだ。パターンの中からパターンが浮かび上がる。生きた、デジタルのフラクタル——経済、社会、人間心理の状態。21 世紀の水晶玉、しかもシリコン製だ! これが製品だ。
そしてそれは最高入札者に売られる!
ではあなたは何だ? 歯車か? 牛か? ボランティアか?
指紋は新しい cookie
サードパーティ cookie がどれだけ騒がれたか覚えているか? EU がその最も偉大な発明の一つ——同意バナー——を打ち出したほどだ。
EU がテクノロジー企業より速く動くなら、それは企業が傍観していた証拠だ。そしてそのうちの一社が、たまたまブラウザ市場の三分の二を握っている。
この芝居はどう進むのか?
Google に拍手を——地球上最大の広告会社だ!
第一幕:圧力——「プライバシーは私たちにとって極めて重要であり、あらゆる活動の根幹にあります。」
2019 年、cookie はまだ熱かった。だがすでに PR 上の負債になっていた。Safari と Firefox はずっと前からブロックしていた。
一年後、Google は約束した:cookie を廃止する!! そしてプライバシー優先の新王朝を打ち立てる、と。
第二幕:目くらまし——「サードパーティ cookie を廃止する代わりに、まったく新しい体験を提供します」
5 年後:人々の関心はとうに cookie より厄介な問題に奪われ、Google が作り出した仕組み(Privacy Sandbox)はお粗末なもので、独占禁止の懸念まで呼び、誰も使っていない。
「では cookie は残そう。ただしあなたの IP アドレスはマスクする!」( ログイン済みでシークレットモードを有効にしている場合に限る)(** 最終的にこれすら果たされなかった)
第三幕:加速——あなたは今、私たちの広告製品でデバイス指紋を使えます
今や誰が誰かを特定する、より良い方法がある!
指紋識別はどう動くのか?
よし、まともに技術の話をしよう。
あなたがあるサイトを訪れる。ブラウザがサーバーにリクエストを送り、サーバーがブラウザに実行させるコードを返す。
リクエストそのものがすでにあなたの情報をさらしている:どのブラウザを使い、ブラウザの言語は何で、どの OS 上で動き、そしてあなたの IP アドレス——サーバーが応答を返すにはそれが必要だ。そして IP はしばしばあなたの位置を露呈する。
そしてコードが動き出す。
いいか、ブラウジングを安全にする上で、私たちは文明レベルでかなり前進してきた。サイトを訪れるだけでウイルスに感染する、そんな時代はとうに終わった。問題は、安全の定義が人によって違うことだ。最も広い合意は隔離で止まる:あるサイトのコードは他のサイトが保存したデータを見られず、許可なくあなたのファイルや他のアプリも見られない。Chrome と Edge はここで止まる。その先へ進むのが Safari(特に iOS/macOS 26+ 上)と Firefox で、安全の定義をプライバシーへと広げたが、それでも指紋識別からあなたを完全には守れない。Brave と Tor はプライバシー優先ブラウザの先頭を走り、後発には Mullvad Browser がある(Mullvad は私の見るところ、市場で最高の VPN サービスの一つだ)。
コードはあなたのハードウェア上で動き、ハードウェアは測定できる。測定値は一貫していて、かつ独特だ。これといった手はないので、今のところ成熟した方法は二つしかない:
- あちこちにノイズを混ぜる。これを farbling と呼び、Brave がそうしている。あなたの指紋を前後で一致させない。
- すべてを常に同じに見せる。そうすればブラウザのユーザーを区別できない。Tor と Mullvad はこの道を行く。
よし、指紋を作ってみよう
指紋を組み立てるデータには二つの出所がある:ネットワークリクエストと、コードが動く環境だ。
ネットワークの層を見ると、データはもろいか、ざっくりしているかのどちらかだ:
- IP アドレス;「理想的な状況」では、一人が常に同じ IP を使うなら、それだけで十分かもしれない。だが現実には人々はモバイル回線で大量に接続し、他人と WiFi を共有し、VPN を使い、あるいは自宅ネットワークの IP が ISP によってローテーションされる。だからもろい。
User-AgentやAccept-Languageといったヘッダー;あなたのブラウザ、OS、バージョン番号、言語設定をさらす。
デバイス上でコードを実行できるなら、そのハードウェアの特徴を測る方法がある(しかも権限ダイアログは一切不要!)。これらの特徴は驚くほど安定している:
- GPU;挙動、ベンダー、ドライバ
- CPU;挙動、ベンダー、スレッド数
- メモリ容量
- ディスプレイ情報;解像度、ピクセル比、リフレッシュレート
- 音声処理
- デバイスモデル
ソフトウェア側も同じだ。インストール済みフォント、拡張機能、システム情報……
何百万台ものデバイスが最新版の Chrome を動かし、何百万台もの Mac が M4 チップを積み、何百万ものブラウザが言語をフランス語に設定している。
だが、M4 上でフランス語の最新版 Chrome を動かしているデバイスだけを見れば、その数はぐっと減る。さらにハードウェアの測定データを加えれば、ほぼ一意と言っていいレベルまで絞り込める。
指紋は本当に地球上で唯一である必要はない。あなたのサンプルサイズの中で人々を区別できれば十分だ。
郵便番号(IP から推定)、生年月日(どこかのプラットフォームで自分から差し出したもの)、そして性別(どこでも記入する)。この三つを合わせれば、アメリカ人の 60% 以上を一意に識別できる。
変数を一つ足せば、候補のプールはさらに狭まる。
情報エントロピー
Akinatorで遊んだことはあるだろうか。頭の中で人物を思い浮かべると、ランプの精が二十数個の質問をして、答えを当ててくる。指紋識別の仕組みは本質的にこれと同じで、質問に答えるのがブラウザに置き換わっただけだ。情報エントロピーを理解すれば、Akinator の魔法はただの単純なトリックにすぎないと分かる。
盤上の人物を当てるゲームで単純化してみよう。質問は「思い浮かべた人物は男性ですか?」のようなものだ。私が「はい」と答え、盤上の人物の半分が男性なら、候補は半分に絞られる。このとき私の回答はlog₂(100 / 50) = log₂(2) = 1ビットの情報を与えたと言える。候補プールが半分になったからだ。
ある回答がもたらすビット数はその驚異度(surprisal)と呼ばれる。答えが珍しいほど、より多くを教えてくれる。
- 2 人に 1 人が持つ特徴は 1 ビット(男性である)
- 8 人に 1 人が持つ特徴は 3 ビット(ひげがある)
- 128 人に 1 人が持つ特徴は 7 ビット(片目しかない)
驚異度は答えの価値を測り、エントロピーは問いの価値を測る。128 人に 1 人が片目なら、この質問をすると 128 回のうち 127 回は「いいえ」が返ってくる。
| 回答 | 確率 | 驚異度 | エントロピーへの寄与 |
|---|---|---|---|
| はい | 1/128 | log₂(128 / 1) = 7 bits | 1/128 x 7 = ~0.055 |
| いいえ | 127/128 | log₂(128 / 127) = ~0.0113 bits | 127/128 x 0.0113 = ~0.011 |
それぞれの起こりうる回答の寄与を足し合わせると、この質問自体は約 0.066 ビットのエントロピーに相当する。つまり、一つの回答から平均して得られるビット数だ。
特徴同士が独立であれば、ビット数をそのまま足すか、比率を掛け合わせればいい。だからひげがあり片目である男性は 11 ビット、2048 分の 1 を意味する。だが Thomas Bayes が教えてくれるように、現実はそう単純ではない。ひげはそれ自体が男性である強い指標であり、男性は片目である可能性も高い。これらの特徴は独立ではないので、ビット数は単純には足せない。
この種の推論には面白い応用がある:
-
医療診断:人口の 0.01% に影響する既知の疾患について、精度 99% の検査で陽性が出たとする。この結果が誤りである確率は、実際に罹患している確率のおよそ 100 倍だ。もっと証拠が必要だ!
-
暗号学:ランダムな 4 単語からなるパスワードは、ランダムなキーボード文字 8 文字と同等の強度がある(しかもずっと覚えやすい!)

-
法医学:人口 100 万人の都市で一人に絞り込むには、およそ 20 ビット必要だ。1000 人に 1 人しか一致しない目撃証言は 10 ビットしか与えず、依然として 1000 人の容疑者が残る。
では何ができるのか
自分のブラウザを試してみよう:
- coveryourtracks.eff.org はあなたの指紋がどれだけ独特かを表示し、各測定データ点のエントロピー値も示してくれる。
Chrome を使っているなら、額に身分証を貼って街を歩いているようなものだ。
Safari と Firefox はある程度の保護を提供するが、高度なトラッカーは依然としてあなたを識別できる。
現時点で、Brave、Tor、Mullvad Browser だけが高度なアンチフィンガープリント保護を実装した主要ブラウザだ。
ブラウザを変えたくないなら、その気持ちは分かる。私自身 Arc の熱心なユーザーだが、残念ながら開発は終了し、プライバシー機能が追加されることは永遠にない。JShelter のような拡張機能もある。ブラウザ API の呼び出しを傍受してフィンガープリントスクリプトを妨害するが、一部のサイトを壊してしまう。Firefox の Resist Fingerprinting 機能も同じ問題を抱えている。
皮肉なことに、プライバシー拡張機能はむしろあなたをより独特にする。使う人が少ないからだ。賢いトラッカーはそれを見分け、拡張機能に妨害された信号を無視し、妨害されていない信号に注目できる。
どんな拡張機能も、ブラウザに組み込まれたエンジンレベルの保護には及ばない。追跡されたくなければ、思い切って乗り換えるしかない。
このページで使っている手法
私はあなたのデバイスに対していくつかの測定を行い、ハッシュを生成しているだけだ。どれか一つでも変化すれば、ハッシュは変わる。専門的なアプリケーションはこれよりはるかに複雑で、単一の変数が変化しても識別の一貫性を保てる。
-
OfflineAudioContextコンプレッサーで短い音をレンダリングするが、再生はしない。結果に現れるわずかな浮動小数点の差異は、ブラウザの音声エンジンと CPU によって決まる。const off = new OfflineAudioContext(1, 5000, 44100); // … a 1 kHz triangle wave into a dynamics compressor … const data = (await Promise.race([off.startRendering(), timeout])).getChannelData(0); let sum = 0; for (let i = 4500; i < 5000; i++) sum += Math.abs(data[i]); return sum.toFixed(3); -
WebGLGPU のベンダーとモデル(バージョン番号は含まない)、GPU とそのドライバが対応する機能、そして小さな三角形をレンダリングした後のピクセルを読み取る。const gl = document.createElement('canvas').getContext('webgl'); const dbg = gl.getExtension('WEBGL_debug_renderer_info'); return gpuName(gl.getParameter(dbg ? dbg.UNMASKED_RENDERER_WEBGL : gl.RENDERER) || ''); // "ANGLE (Apple, ANGLE Metal Renderer: Apple M4, Unspecified Version)" -> "apple m4" // … return fnv1a(new TextEncoder().encode([...(gl.getSupportedExtensions() || []).sort(), ...limits, ...precision].join('|'))); // … gl.drawArrays(gl.TRIANGLES, 0, 3); gl.readPixels(0, 0, canvas.width, canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, px); -
canvasいくつかのフォント、emoji、グラデーションでテキストを描画し、ピクセルを読み戻す。アンチエイリアスとフォントレンダリングは、OS、GPU、フォントによって変わる。ctx.font = '15px "Times New Roman", serif'; ctx.fillText('Sphinx of black quartz 🦊', 4, 22); // … const data = ctx.getImageData(0, 0, 240, 60).data; -
Intlあなたのタイムゾーン、日付と数値のフォーマット。VPN は IP の位置を変えるが、タイムゾーンは変わらない。const date = Intl.DateTimeFormat().resolvedOptions(); // … return [date.timeZone, date.locale, date.calendar, date.numberingSystem, hourCycle, (1234567.891).toLocaleString()].join('/'); -
navigatorCPU のコア数、メモリ容量(Chrome のみ)、ブラウザの言語。return [navigator.hardwareConcurrency, navigator.deviceMemory, navigator.language].join('/'); -
crypto.subtleすべての値を SHA-256 でハッシュ化し、そのハッシュ結果が、あなたのニックネームの特徴ひとつと動物一匹を決める。const digest = await crypto.subtle.digest('SHA-256', bytes); // … nickname: stranger || `${pick(TRAITS, hex, 0)} ${pick(ANIMALS, hex, 8)}`,