深掘り

EXIF メタデータ:あなたの写真に潜むプライバシー漏洩の技術ガイド

koboshiCo-founder
·4 分で読めます
EXIF メタデータ:あなたの写真に潜むプライバシー漏洩の技術ガイド
要約

スマートフォンやカメラで撮った写真には、どれも内部にもう 1 つのファイルが潜んでいる。撮影設定、タイムスタンプ、シリアル番号、多くの場合は GPS 座標だ。EXIF のバイトレベルの構造、その調べ方、漏洩が起きる仕組み、そしてフォーマット変換がそれを消してくれる理由を解説する。

iPhone で写真を撮り、その JPEG を十六進エディタで開いてみよう。FF D8 の開始マーカーから数百バイト進むと、次のようなバイト列が見つかる:

FF E1 1C 24 45 78 69 66 00 00 4D 4D 00 2A 00 00 00 08

FF E1 は APP1 セグメントマーカーで、その後の 2 バイトがセグメント長だ。続く 6 バイトは Exif\0\0 という文字列で、その直後には TIFF ヘッダー(4D 4D 00 2A はビッグエンディアンを示す)が続く。あなたの JPEG は内部にもう 1 つの小さなファイルを抱えており、そちらは画像そのものよりも多くのあなたの情報を明かしてしまうことが多い。

EXIF とは何か

EXIF は Exchangeable Image File Format の略だ。JEIDA(日本電子工業振興協会)が 1995 年にバージョン 1.0 を公開した。現在は JEITA と CIPA が標準を保守しており、EXIF 3.0 は 2023 年に登場した。

構造的には、EXIF は TIFF だ。Exif\0\0 ヘッダーの後にバイトオーダーマーカーが来て、続いて Image File Directory(IFD)のチェーンが続く。各 IFD エントリは 12 バイト:

Bytes 0-1:   タグ ID(例: 0x010F = Make)
Bytes 2-3:   データ型(ASCII、rational、short、long)
Bytes 4-7:   値の個数
Bytes 8-11:  インライン値、または値へのオフセット

プライバシー上重要なサブディレクトリが 2 つある。EXIF SubIFD(タグ 0x8769 が指す先)にはカメラ設定、シリアル番号、タイムスタンプが格納される。GPS IFD(タグ 0x8825)は緯度と経度をそれぞれ 3 つの有理数(度、分、秒)として保存する。

多くの場合、IFD1 にもサムネイルが格納されている。メタデータ内に埋め込まれた小さな JPEG で、この点は後で重要になるので覚えておいてほしい。

EXIF を格納するコンテナ:

フォーマットEXIF の格納場所備考
JPEGAPP1 セグメントEXIF が生まれた場所
HEICmeta box 内の Exif アイテムiOS 11 以降の iPhone デフォルト
WebPVP8X 内の EXIF チャンクオプション、存在しないことも多い
PNGeXIf チャンク2017 年に仕様へ追加
TIFFファイル自体が TIFFEXIF の親フォーマット
BMP/ICO非対応メタデータ構造をまったく持たない

カメラが EXIF を書き込むようになった理由

90 年代半ばの問題は、ありふれた実務的なものだった。デジタルカメラは文脈情報をまったく持たないファイルを生み出した。フィルムの写真家にはネガがあり、現像日が書かれたラボの封筒があり、メモがあった。デジタルで撮る側が手にしたのは、DSC_0042.JPG だらけのディレクトリだけで、他には何もなかった。

EXIF は 3 つの具体的なニーズを解決した:

  • 露出の記録。絞り、シャッタースピード、ISO、焦点距離を残しておけば、うまくいった写真の理由を後から振り返り、同じ条件を再現できる。
  • プリント注文。DPOF(Digital Print Order Format)により、カメラ上で写真にマークを付けておき、後でキオスクでプリントできた。回転などの EXIF フィールドが使われた。
  • 向きとプレビュー。Orientation タグが縦位置で撮った写真を正しい向きに保ち、埋め込みサムネイルがカメラの LCD での閲覧を速くした。

これらすべての根底には、ある暗黙の前提がある。写真は所有者の手元に留まるという前提だ。EXIF は、写真が CF カードからハードドライブへ、そしてプリントキオスクへと移動する世界のために設計された。1995 年の JEIDA の誰も、1 日に十数枚の写真を公開サーバーへアップロードする世界など想定していなかった。

実際に何が入っているのか

スマートフォンで撮った写真をメタデータリーダーで開くと、タグの一覧がずらりと並ぶ。プライバシー上重要なのは次のフィールドだ:

タグ値の例何が分かるか
Make / ModelApple, iPhone 15 Pro使っているハードウェア
BodySerialNumber / LensSerialNumberデバイスごとに一意カメラの指紋
DateTimeOriginal + OffsetTime2026:06:30 18:42:11 +09:00秒単位の撮影時刻
GPSLatitude / GPSLongitude37°46'29" N, 122°25'10" W誤差数メートルの位置情報
GPSAltitude14.2 mおおよその階数
SoftwareInstagram, Photoshop 26.1ファイルを処理したソフト
Artist / Copyright自由テキスト時には実名
IFD1 サムネイルもう 1 つの JPEG編集前の画像のコピー

実際の iPhone の写真を exiftool にかけた出力(長いので抜粋):

$ exiftool IMG_4021.HEIC
Make                            : Apple
Camera Model Name               : iPhone 15 Pro
Serial Number                   : F2LX8A1BCD
Date/Time Original              : 2026:06:30 18:42:11
GPS Latitude                    : 37 deg 46' 29.28" N
GPS Longitude                   : 122 deg 25' 10.41" W
GPS Altitude                    : 14.2 m Above Sea Level

たった 30 秒目を通しただけで、見ず知らずの他人でも、あなたの撮影機材、撮影日時、そしてその場所が誤差数メートルでどこかまで分かる。

自分のマシンで読み取る方法

Windows

ファイルを右クリックして「プロパティ」を開き、「詳細」タブを表示する。メーカー、モデル、日付、GPS 座標がすべてここに並んでいる。同じタブの下部にある「プロパティや個人情報を削除」リンクをクリックすると、簡易的な削除ダイアログが開く。

PowerShell から直接読み取る場合:

Add-Type -AssemblyName System.Drawing
$img = [System.Drawing.Image]::FromFile("C:\photos\IMG_4021.jpg")
$img.PropertyItems | ForEach-Object {
    $text = [System.Text.Encoding]::ASCII.GetString($_.Value).Trim([char]0)
    "Tag 0x{0:X4} (len {1}): {2}" -f $_.Id, $_.Len, $text
}
$img.Dispose()

数値フィールドは生バイトのまま出てくるが、Make や Software のような ASCII タグはきれいに表示される。

macOS

「プレビュー」で画像を開き、「ツール」メニューから「インスペクタを表示」を選んで、EXIF タブと GPS タブを確認する。GPS タブでは地図上にピンまで表示される。

ターミナルでは、mdls で Spotlight がインデックスした情報をすべて一覧できる:

mdls IMG_4021.jpg | grep -iE "gps|latitude|longitude|model"

あるいは brew install exiftool で ExifTool をインストールすれば、すべてのタグを表示できる。

Linux

標準は ExifTool だ:

exiftool IMG_4021.jpg

もっと軽い選択肢:exiv2 IMG_4021.jpg、あるいは ImageMagick の identify -verbose IMG_4021.jpg | grep -i exif

ブラウザから、20 行の TypeScript で

APP1 セグメントを自分で見つけるには、JPEG のマーカーチェーンをループでたどる:

async function findExifSegment(file: File): Promise<number> {
  const bytes = new Uint8Array(await file.slice(0, 128 * 1024).arrayBuffer())
  if (bytes[0] !== 0xff || bytes[1] !== 0xd8) return -1 // not a JPEG

  let offset = 2
  while (offset < bytes.length - 12) {
    if (bytes[offset] !== 0xff) break
    const marker = bytes[offset + 1]
    const length = (bytes[offset + 2] << 8) | bytes[offset + 3]
    if (
      marker === 0xe1 &&
      String.fromCharCode(...bytes.slice(offset + 4, offset + 10)) ===
        "Exif\0\0"
    ) {
      return offset
    }
    offset += 2 + length
  }
  return -1
}

EXIF がプライバシーを漏洩させる仕組み

GPS 座標があなたの居場所を明かしてしまう

スマートフォンは、カメラアプリに位置情報の権限があると GPS を記録する。ほとんどの人は、最初に一度だけ許可をタップして、そのまま忘れてしまっているのが実情だ。ベランダやデスク、子どもの学校の課題の写真をフォーラムやフリマサイトの出品に投稿すれば、メートル単位の精度で自分の住所を公開したことになる。

有名な事例が John McAfee だ。2012 年 12 月、彼は逃亡中でグアテマラに潜伏していた。Vice が iPhone 4S で撮影された彼の写真を公開したところ、EXIF データには完全な GPS 座標が含まれており、グアテマラ国内のどこに彼がいるかが誰にでも正確に読み取れた。数日後、彼はグアテマラ当局に身柄を拘束された。

シリアル番号がアカウントを結びつける

BodySerialNumber と LensSerialNumber はデバイスごとに一意だ。同じカメラで撮影された写真を投稿する 2 つの匿名アカウントは、ほぼ確実に結び付けられる。まさにこの理由で、研究者たちは写真サイトをクロールし、カメラのシリアル番号で画像をクラスタリングしてきた。オンラインで自分の身分を使い分けることはできても、カメラはそうした区別を付けてくれない。

タイムスタンプが生活リズムを描き出す

DateTimeOriginal に、タイムゾーンオフセットが加わる。1 つのタイムスタンプだけでは大した情報にはならないが、1 年分のアップロードが集まれば、あなたがいつ起き、いつ家を出て、いつ旅行に出るかが見えてくる。

サムネイルがあなたを裏切る

IFD1 のサムネイルは、メタデータ内にある独立した JPEG だ。メイン画像から顔や書類を切り抜いても、多くのエディタは元のサムネイルをそのまま残す。それを抽出した人は、切り抜き前の写真を手に入れることになる。2003 年、TechTV の司会者が自分の切り抜き写真を投稿したところ、読者が EXIF サムネイルから元のフレーム全体を復元した。この教訓が今も語り継がれているのは、ツールが今も同じ間違いを繰り返しているからだ。

アップロード後も EXIF が生き残る場所

大手ソーシャルプラットフォーム(Facebook、Instagram、X)はアップロード時に画像から EXIF を除去する。それ以外はほぼ除去しない。メール添付、フォーラムへのアップロード、フリマサイトの出品、クラウドドライブの共有リンク、AirDrop、そしてオリジナル画質で送信する設定のメッセンジャーだ。ファイルがそのままの形でデバイスを離れるなら、メタデータも一緒に出ていく。

フォーマット変換で何が起きるか

写真を変換しても、自動的にメタデータが除去されるわけではない。コンバーターには 2 種類ある:

  1. メタデータコピー型。再エンコードしながらタグを意図的に引き継ぐツール。ExifTool、ffmpeg、そして「メタデータを保持」がデフォルトのほとんどの GUI コンバーターがこれにあたる。コピー型で JPEG を WebP に変換すれば、GPS 座標はそのまま WebP の EXIF チャンクへ移動する。
  2. ピクセル再エンコード型。生ピクセルにデコードし、そこからまったく新しいファイルをエンコードするツール。メタデータはピクセルの一部ではないため、出力には画像データしか含まれない。

手動で消すなら、どちらの場合もコマンド 1 つで済む:

# ExifTool: wipe every tag, keep the image
exiftool -all= -overwrite_original photo.jpg

# ImageMagick 7: re-encode without metadata
magick photo.jpg -strip photo-clean.jpg

ここで 1 つ注意が必要なのが向きだ。EXIF Orientation(タグ 0x0112)は表示側に画像の回転を指示するもので、多くの場合 90 度だ。その回転をピクセルに反映させないままタグを除去すると、縦位置で撮った写真はすべて横向きで出力されてしまう。正しい手順は、向きを適用した状態でデコードしてからメタデータを捨てることだ。回転を処理せずに除去するツールは、除去しないよりかえって悪い。

当サイトのコンバーターが EXIF に対して行うこと

当サイトのすべてのコンバーターはピクセル再エンコード型だ。パイプラインは全ツールで同一:

  1. ソースファイルをブラウザ内で生ピクセルにデコードする(HEIC には libheif の WebAssembly ビルド、それ以外にはブラウザネイティブのデコーダーを使用)。
  2. デコード時に EXIF の向きを適用済みの状態で、ピクセルをキャンバスに描画する。
  3. キャンバスをターゲットフォーマットへエンコードする。

出力ファイルが保持するのは圧縮されたピクセルだけで、他には何もない。APP1 セグメントも、EXIFeXIf チャンクも、GPS IFD も、シリアル番号も、埋め込みサムネイルもない。メタデータをコピーするコードパスは存在しない。コピーできるメタデータがメモリ上にそもそも存在しないからだ。そして全体がクライアントサイドで動くため、ファイルはデバイスから離れず、どのサーバーも元ファイルを見ることはない。

ソースフォーマットを選んでほしい:

ファイルをドロップして、変換後のコピーをダウンロードし、代わりにそちらを共有すればいい。ピクセルは同じままで、メタデータは消えている。

要約

  • EXIF が生き残る場所(メール、フォーラム、フリマサイト、直接リンク)で写真を共有する前に、まず確認する。Windows では「プロパティ」、macOS ではインスペクタ、Linux では exiftool だ。
  • ファイルに GPS データが含まれ、それを残したくないなら、変換する。上でリンクしたすべてのツールはピクセルのみを出力する。
  • 別々の身分を使い分けて投稿しているなら、カメラのシリアル番号がそれらを結び付けられる可能性がある。これも除去で対処できる。
  • オリジナルは手を付けずに残しておく。自分のアーカイブの中では、EXIF は純粋に有用だ。クリーンにすべきは、公開するコピーの方だ。

その他のおすすめ記事