case03 ・ 再識別デモ

「ハッシュ化=匿名化」ではない

2014年の米国ニューヨーク市タクシーデータの再識別(V. Pandurangan ほか)と、
「ハッシュ化は匿名化ではない」という整理(EU 第29条作業部会)を参考にした、仮想の事例(デモ)

データはすべて教材用の合成データです。

はじめに — 2つの重要な注意

① 法域についての注意

参考にした事例は 海外の事例 です。以降で触れる日本の制度(個人情報保護法・委員会規則)への言及は、
もし同種の事象を日本の制度に当てはめて考えたら」という 仮定の説明 であり、
この事例が日本で法的に判断された、という意味ではありません。

② この教材の目的

攻撃を推奨するためではなく、安易な匿名化がいかに脆いかを具体的に理解し、正しい対策に結びつけるためのデモです。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

case01・02 との立ち位置の違い

case01 / case02 case03
視点 うまく加工する側 弱い加工が破られる側
進む順序 事例 → 評価 → 加工設計 → 実装 → 結果 公開データ → 弱点の評価攻撃の設計 → 実装 → 結果
学ぶこと 加工方針をどう決めるか 「加工したつもり」がなぜ・どう破れる
7ステップの骨格は同じ。ただし「加工」の位置に **攻撃** が入ります。
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

1/7 ・ 事例概要

タクシー事業者が、走行履歴を「匿名化したつもり」で公開した。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

あらすじ

タクシー事業者が、運転者の 走行履歴(誰が・いつ・どこからどこへ運んだか)を外部公開することにしました。

運転者本人が特定されないよう 匿名化したつもり で、履歴の 運転者ID を SHA-256 でハッシュ化 した
「ハッシュ化済み履歴」を公開します。

ところが

ある利用者(攻撃者)が、2つの弱点を突いて 公開データの運転者IDをすべて復元 してしまいました。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

攻撃者が突いた2つの弱点

① IDの形式が公知だった

運転者IDは 100-000-000 のような決まった桁形式。
しかも先頭の事業者コードは公表・固定。

→ 取りうるIDの候補が少ない(低エントロピー

② ハッシュ化が単純すぎた

秘密鍵もソルトも使わない、
素の SHA-2561回かけただけ

→ 同じIDは誰が計算しても同じ値

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

攻撃者がやったこと

  1. 自分が乗ったタクシーの運転手のID(乗務員証で確認できる)を SHA-256 にかけた。
  2. 公開データの中に 同じ値 を見つけた。
    → これで「加工方法は無ソルトの SHA-256」だと 確定(弱点②)。
  3. 公知のID形式で すべての候補を総当り してハッシュを計算し、ハッシュ→ID の対応表 を作った(弱点①)。
  4. 公開履歴の運転者IDを まるごと復元 した。
たった1つの既知の平文が

加工方法の全体を暴く鍵になります。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

なぜ「ハッシュ化=匿名化」ではないのか(技術の面)

ハッシュ関数は、同じ入力からは 必ず同じ値 を出します。

裏を返すと、**取りうる入力を片端から計算して一致を探せば、元の入力を言い当てられる**ということ。
  • IDの形式が公知だと候補が絞られるため、この総当り(辞書攻撃/レインボーテーブル)が
    現実的な時間 で終わってしまいます。
  • ハッシュ化は仮名化の技術(安全管理措置)の一つではありますが、
    それだけで復元できない状態になるわけではありません
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

なぜ危険なのか(法律の面 ※日本の制度に当てはめた仮定の整理)

匿名加工情報ではない

再識別も復元もできないよう、連結符号の削除・特異な記述の削除・一般化などの基準(施行規則第34条)で加工したものが匿名加工情報。

本件は運転者IDをハッシュ化しただけで 基準を満たさない

仮名加工情報でもない

照合しなければ本人を識別できないように加工し、識別行為の禁止などの義務のもとで扱うもの。
ただし 原則として公表・第三者提供はできません

本件は外部公開が前提の時点で整合しない。

結論

匿名加工情報でも(適切に運用される)仮名加工情報でもない、制度上の位置づけがあいまいなまま公開されたデータ

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

元データと公開データ

データ 内容 立場
運転者マスタ(drivers 運転者ID・氏名・営業所 事業者だけが持つ(非公開
走行履歴(trips 運転者IDに紐づく乗降・料金の記録 事業者の内部データ
ハッシュ化済み履歴(公開) 走行履歴の運転者IDを SHA-256 に置換したもの 一般公開
攻撃者が手にできるのは 公開されたハッシュ化済み履歴だけ。それでも元IDを復元できてしまいます。
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

2/7 ・ データを見る

まず、公開されたデータそのものを。
「もう匿名化できていそうか?」を自分の目で確かめてください。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

公開されたデータ:ハッシュ化済み走行履歴

事業者は走行履歴の 運転者ID を SHA-256 に置き換え、走行IDを落として一般公開しました(全 17,950 行)。
氏名も、元の運転者IDも、表には出てきません。

項目 内容
運転者ハッシュ 運転者IDを SHA-256 にかけた16進64桁
乗車日時 そのまま
乗車地・降車地 そのまま
走行距離km・料金 そのまま
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

公開データのサンプル(すべて合成データ)

運転者ハッシュ 乗車日時 乗車地 降車地 走行距離km 料金
87145a71…a542d79 2026-06-30 20:43:29 羽田空港 池袋 5.3 2812
9b1d3c7e…f0a24e6 2026-04-02 08:11:05 品川 銀座 4.1 2180
4a8f012b…c3d59071 2026-05-18 22:47:39 新宿 渋谷 3.6 1930

運転者ハッシュは、規則性の無い長い文字列に見えます。氏名も運転者IDも無いので、一見すると「誰の記録か」は分かりません

これで匿名化できている?

意味のなさそうなハッシュに置き換えたのだから、もう個人は分からない —— そう見えます。本当にそうでしょうか?

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

舞台裏:事業者だけが持つ元データ(非公開)

データ 主キー 1レコード 件数 公開範囲
drivers(運転者マスタ) 運転者ID 運転者1人 2,000 非公開
trips(走行履歴) 走行ID 走行1件 17,950 非公開

drivers: 運転者ID / 氏名 / 営業所

trips: 走行ID / 運転者ID / 乗車日時 / 乗車地 / 降車地 / 走行距離km / 料金

公開したハッシュ化済み履歴は、この trips の運転者IDをハッシュに置き換えて作ったものです。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

3/7 ・ 弱点の評価

「なぜ運転者ハッシュが元に戻せるのか」を、
ハッシュ化の性質IDの作り の両面から評価します。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

見るポイント(4つ)

観点 内容
ハッシュ関数の性質 同じ入力からは必ず同じ出力(決定的)。逆算する式は無いが、入力を総当りして一致を探せば元の入力が分かる
エントロピー(候補の多さ) 元の値が取りうるパターンが少ないほど総当りが早く終わる。IDの桁形式が公知だと候補が絞られる
ソルト/秘密鍵の有無 無いと同じIDは誰が計算しても同じハッシュになり、事前計算した対応表(レインボーテーブル)で一気に照合できる
既知の平文があるか 「1つでも」元のIDとそのハッシュの組を掴めると、加工方法そのものを言い当てられる
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

2つの弱点

弱点 具体的な状態 なぜ危険か 攻撃で果たす役割
① 形式が公知・低エントロピー 運転者IDは 100-000-000 形式。先頭の事業者コード 100 は公表・固定。候補は残り6桁=約100万通り(10⁶) 取りうるIDを全列挙できる。全部ハッシュしても数秒 総当りで ハッシュ→ID の対応表を作れる
② 単純な無ソルト SHA-256 ソルト・秘密鍵なしで SHA-256 を1回 同じIDは誰が計算しても同じハッシュ。事前計算・使い回しが効く 既知IDのハッシュ一致で加工方法を確定できる
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

エントロピーの直感

安全な場合

IDが「予測不能な十分に長いランダム値」(例: 128ビットの乱数)なら、
候補が 天文学的 で総当りは不可能。

本件の場合

桁形式が決まっていて、しかも公表されている部分があるため、
実際に試すべき候補は 約100万通り に縮む。

弱点①の本質

「形式が公知」=「候補が少ない」=「総当りできる」 という連鎖。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

ソルト・秘密鍵があると何が変わるか

  • ソルト(値ごとに違うランダム値を足してハッシュ)
    → 同じIDでも出力がバラけ、事前計算した対応表が使えません

  • 秘密鍵つきハッシュ(HMAC)
    → 鍵を知らない攻撃者は正しいハッシュを再現できず、総当りしても一致しません

本件はどちらも無し。だから「素の SHA-256 で総当り」がそのまま通ってしまいます。
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

公開データの各項目は再識別に使えるか

項目 性質 再識別での役割
運転者ハッシュ 運転者IDの無ソルト SHA-256 復元対象。総当りで元の運転者IDに戻せる(弱点①②)
乗車日時 行動・履歴 復元後、同一運転者の行動を時系列で追える
乗車地・降車地 行動・履歴 復元後、営業所・生活圏の推定につながる
走行距離km・料金 行動・履歴 補助的(他項目と組み合わせ)
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

4/7 ・ 攻撃の設計

2つの弱点を、どう組み合わせれば再識別できるか。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

攻撃の全体像

入力
公開データ(ハッシュ化済み履歴) 攻撃者が知っている1件(自分が乗った運転手のID)
① 方法の特定
sha256(既知ID)公開データに一致するか無ソルト SHA-256 と確定
② 対応表の構築
100-NNN-NNN を全列挙(10⁶)ハッシュ→ID の逆引き表
③ 全復元
公開履歴の各行「誰が」いつ・どこを走ったか

①で一致しなければ、別の加工方法(ソルト・鍵・別アルゴリズム)を疑うことになります。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

各ステップの狙い

ステップ やること 効かせる弱点 得られるもの
① 加工方法の特定 既知の運転者IDを SHA-256 にかけ、公開データのハッシュ列に一致があるか確認 ② 単純な無ソルト SHA-256 「加工は無ソルト SHA-256」という確証
② 対応表の構築 公知フォーマット 100-NNN-NNN の**全候補(約100万通り)**を計算し、ハッシュ→ID の対応表を作る ① 形式が公知・低エントロピー 逆引き表(レインボーテーブル相当)
③ 全復元 公開履歴の各行の運転者ハッシュを対応表で引き当て、元の運転者IDに置換 ①② の合わせ技 運転者IDを復元した走行履歴
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

なぜ「①方法の特定」が要るのか

総当り(②)はいつでもできる。いきなり総当りではダメなのか?

加工方法が分からなければ「何を」総当りすべきか決まりません
(ソルト付きか、HMAC か、そもそも別アルゴリズムか)。

攻撃者は既知の1件を使って、「素の SHA-256 を全候補にかければ一致する」と 先に確かめて から、
安心して総当りに進みます。

たった1つの既知の平文が、加工方法全体を暴く鍵になる —— ここが弱点②の怖さです。
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

①と②がそろうと何が起きるか

①だけ

方法は分かるが候補が無限。

→ 総当りは非現実的で 復元できない

②だけ

候補は少ないが方法が不明。

→ 何を計算すればいいか 分からない

①+②(本件)

「素の SHA-256 を、約100万通りの候補に」総当りするだけ。

数秒で全運転者IDが復元

攻撃が成立する条件を裏返すと、そのまま 対策 になります(7/7 で扱います)。
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

5/7 ・ 攻撃の仕様

手順を、具体的な処理に落とし込みます。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

前提:攻撃者が持っているもの

公開データ

ハッシュ化済み履歴
(運転者ハッシュ+乗降・料金)

公知の知識

運転者IDの形式 100-NNN-NNN
(先頭の事業者コード 100 は固定・公表)

既知の1件

自分が乗ったタクシー運転手の運転者ID
(乗務員証に表示)

つまり

特別な内部情報は不要。公開データ+公知の形式+自分が1回タクシーに乗った経験だけで成立します。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

主なルール

  • ハッシュ化(事業者側の加工・比較用に再現): 運転者ハッシュ = sha256(運転者ID) の16進64桁。ソルト・秘密鍵なし。走行IDは公開時に落とす。
  • ① 加工方法の特定: sha256(既知の運転者ID) を計算し、公開データの 運転者ハッシュ 集合に含まれるかを確認。含まれれば「無ソルト SHA-256」で確定。
  • ② 対応表の構築(総当り): 100-{000..999}-{000..999} の**全候補(10⁶)**を生成し、それぞれの SHA-256 を計算。公開データに出現するハッシュだけを ハッシュ → 運転者ID の辞書に記録する(メモリ節約)。
  • ③ 全復元: 公開履歴の各行の 運転者ハッシュ を対応表で引き、復元運転者ID 列を付与。必要なら運転者マスタと突き合わせて氏名・営業所まで再識別する。
  • 対策の検証: 事業者が HMAC-SHA256(秘密鍵, 運転者ID) で加工していた場合、攻撃者は鍵を知らないので、同じ総当りでは 1件も一致しない ことを確認する。
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

攻撃仕様一覧(処理ごと)

段階 入力 処理 出力
ハッシュ化(再現) 走行履歴の運転者ID 無ソルト sha256 運転者ハッシュ
① 方法特定 既知の運転者ID sha256 して公開集合と照合 一致(True/False)
② 対応表 公知フォーマットの全候補 10⁶ sha256 を計算し公開ハッシュに一致するものを記録 ハッシュ→ID 辞書
③ 全復元 公開履歴の運転者ハッシュ 対応表で逆引き 復元運転者ID(全行)
検証 復元運転者ID 元の走行履歴の運転者IDと比較 全件一致(assert)
対策 HMAC で加工した公開ハッシュ 素の sha256 で総当り 一致0件(復元不能)

計算量の目安: 候補は約100万通り。短い文字列の SHA-256 を100万回計算しても、一般的な PC・Colab で 数秒
(仮に9桁すべてが自由なら 10⁹ 通りで桁違いに重くなりますが、事業者コードの公知性がそれを 10⁶ に縮めています。)

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

6/7 ・ 実装(Colab)

notebooks/case03_reidentification.ipynb

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

Notebook でやること

流れ

  1. 合成データ(drivers / trips)を取得
  2. 事業者側の加工を再現し、公開データを作る
  3. ① 既知IDのハッシュで方法を特定
  4. ② 10⁶ 候補を総当りして対応表を構築
  5. ③ 公開履歴の運転者IDを全復元
  6. 元データと突き合わせて 全件一致 を確認
  7. 対策の検証: HMAC ならどうなるか
このデモの締めくくり

攻撃を再現して終わりではなく、
7. 対策が効くことを同じコードで確かめるところまでが1セット。

「破られる」と「守れる」を並べて見ることに意味があります。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

7/7 ・ 結果とチェック・対策

何が起きたか。そして、どう防ぐべきだったか。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

データ規模と攻撃① の結果

データ 件数
drivers(運転者マスタ) 2,000
trips(走行履歴) 17,950
公開された運転者ハッシュ(種類) 2,000

① 加工方法の特定

  • 既知の運転者ID: 100-001-001
  • sha256("100-001-001") = 87145a71…5a542d79
  • この値は 公開データの運転者ハッシュに存在した

→ 加工は「無ソルト SHA-256」だと 確定

たった1件、元IDとハッシュの対応が分かるだけで、加工方法の全体が割れてしまいます(弱点②)。
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

攻撃② 総当りで全復元

指標
総当りした候補数 1,000,000(10⁶)
復元できた運転者ハッシュ 2,000 / 2,000(100%)
運転者IDを復元した走行履歴 17,950 行すべて
復元結果と元データの一致 全件一致
総当りの所要時間の目安 数秒
ハッシュ列は復元運転者IDに戻せるため、実質的に 運転者IDを平文公開したのと変わりません
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

確認テスト結果(すべて合格)

  • ✅ 既知IDのハッシュが公開データに一致する(加工方法を特定できる)
  • ✅ 公知フォーマットの全列挙(10⁶)で 2,000 種の運転者ハッシュをすべて復元できる
  • ✅ 復元した運転者IDが、元の走行履歴の運転者IDと全 17,950 行で一致する
  • ✅ 秘密鍵つきハッシュ(HMAC)で加工した場合、同じ総当りでは 0 件しか復元できない
最後の1つが対策の実証。同じ攻撃コードが通らなくなることを確かめています。
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

再識別で何が分かってしまうか

運転者IDが復元されると、乗降・日時・料金は もともと平文 なので、特定の運転者の行動が丸ごと追えます。

営業所 最も多い乗車地
新宿営業所 新宿
渋谷営業所 渋谷
羽田営業所 品川
個々の運転者では、いつ・どのエリアを流し、どこへ客を運んだかという 生活・勤務のパターン まで見えてしまいます。
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

安易な匿名化が危険な2つの理由

何が問題か このデモでの現れ方
技術 元の値の候補が少なく(低エントロピー)ハッシュが単純(無ソルト・鍵なし)なら、総当りで復元できる 100万通りの総当りで 2,000種を全復元・17,950行が全一致(数秒)
法律 匿名加工情報の作成基準(施行規則第34条)を満たさず匿名加工情報ではない。公表・第三者提供を前提にする点で仮名加工情報の取り扱いにも当てはまらない 「匿名化したつもり」で公開したデータが、どちらの制度にも乗らない中途半端な状態
技術だけ・法律だけを見ても足りません。「復元できないか(技術)」と「制度の要件を満たすか(法律)」の両方を確かめる必要があります。

※ ここでの「法律」は、もし同種の事象を日本の制度に当てはめて考えたらという仮定の整理です。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

どう防ぐべきだったか(対策)

攻撃が成立した条件(弱点①②)を裏返すと、技術面の対策になります。

  • 秘密鍵つきハッシュ(HMAC)にする
    HMAC-SHA256(秘密鍵, 運転者ID) なら、鍵を知らない攻撃者は同じ値を再現できず、総当りしても一致しません(本デモで 復元 0 件 を確認)。鍵は公開データと 分離して厳重に管理 します。
  • ソルトを付ける
    値ごとに異なるランダム値を足してからハッシュすると、事前計算した対応表(レインボーテーブル)が使えなくなります。
  • そもそも個人単位の識別子を残さない
    十分に長いランダムな仮IDへ置換し、元IDとの対応表を残さない(=匿名加工の考え方 / case02)。連結符号を断てば、行動履歴を特定の個人へ結び付けられません。
  • 粒度を落とす・集計する
    個票のまま公開せず、エリア・時間帯などに 一般化 して、そもそも個人を追えなくします。
case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

まとめ — 正しく理解して運用する

ハッシュ化=匿名化ではありません

個人を識別する符号を「ハッシュ化しただけ」で公開・第三者提供するのは 安易な匿名化 であり、
技術(復元される)・法律(どちらの制度にも乗らない)の両面で危険です。

大切なのは、法令・委員会規則と、その実装例(どう加工すれば要件を満たすか)を把握し、
正しく理解したうえで運用できるようにする
こと。

技術的な対策(鍵つきハッシュ・連結符号の削除・一般化)と、
制度上の位置づけ(匿名加工情報/仮名加工情報の作成基準と取り扱い義務)を、目的に応じて揃える必要があります。

制度の具体的な要件は最新のガイドライン・委員会規則で確認してください。

case03 再識別デモ | 仮名加工情報・匿名加工情報 事例再現デモ

次は case04 ・ 再構築デモ

個票を出さず「集計統計だけ」を公表すれば安全か?

出典: 2014年 NYC タクシーデータの再識別(V. Pandurangan ほか)/
ハッシュ化と匿名化の区別(EU 第29条作業部会 意見05/2014 等)
サイト: https://gghatano.github.io/pets-seminar-01/
ライセンス: 教材コンテンツ CC BY 4.0 / コード MIT