深度解析

EXIF 詮釋資料:照片隱私洩漏的技術解析

koboshiCo-founder
·4 分鐘閱讀
EXIF 詮釋資料:照片隱私洩漏的技術解析
概述

手機或相機拍出的每張照片,內部都藏著第二個檔案:拍攝設定、時間戳、序號,通常還有 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 區段標記。它後面的兩個位元組是區段長度。接下來六個位元組拼出 Exif\0\0,緊跟在後的是一個 TIFF 標頭(4D 4D 00 2A 代表大端序)。你的 JPEG 裡還藏著第二個更小的檔案,而它透露的關於你的資訊,往往比影像本身還多。

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 項目都是十二個位元組:

Bytes 0-1:   Tag ID (e.g. 0x010F = Make)
Bytes 2-3:   Data type (ASCII, rational, short, long)
Bytes 4-7:   Value count
Bytes 8-11:  Inline value, or an offset to it

對隱私而言,有兩個子目錄特別關鍵。EXIF SubIFD(由標籤 0x8769 指向)保存相機設定、序號和時間戳。GPS IFD(標籤 0x8825)則把緯度和經度各存成三個有理數:度、分、秒。

IFD1 裡通常還存著一張縮圖,一個嵌在詮釋資料(metadata)裡的小 JPEG。先記住這一點,後面會用到。

哪些容器攜帶 EXIF:

格式EXIF 位置說明
JPEGAPP1 區段EXIF 的發源地
HEICmeta box 中的 Exif 項目iOS 11 起為 iPhone 預設
WebPVP8X 內的 EXIF chunk非必要,經常沒有
PNGeXIf chunk2017 年加入規格
TIFF檔案本身就是 TIFFEXIF 的母格式
BMP/ICO不支援完全沒有詮釋資料結構

相機為什麼開始寫入它

1990 年代中期要解決的問題很平凡,也很實際。數位相機產生的檔案沒有任何上下文。底片時代的人有底片、印著沖洗日期的沖印店信封和筆記,數位相機使用者卻只有一個塞滿 DSC_0042.JPG 的資料夾,除此之外什麼都沒有。

EXIF 解決了三個具體需求:

  • 曝光記錄。光圈、快門速度、ISO 和焦距,攝影師得以回顧一張照片為什麼成功,並重現同樣的拍法。
  • 列印訂單。DPOF(Digital Print Order Format,數位列印訂單格式)讓你在相機上標記照片,之後拿到沖印亭列印,過程中會用到旋轉等 EXIF 欄位。
  • 方向與預覽。Orientation 標籤讓直幅照片保持直立,內嵌縮圖則讓相機 LCD 瀏覽照片更快。

注意這一切背後的假設:照片會留在擁有者手上。EXIF 是為一個照片從 CF 卡到硬碟再到沖印亭的世界設計的。在 1995 年的 JEIDA,沒有人料到有一天你會每天把十幾張照片上傳到公開伺服器。

裡面到底有什麼

用詮釋資料讀取工具開啟任何一張手機照片,標籤清單會拉得很長。其中和隱私最相關的欄位:

標籤範例值它洩漏了什麼
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 縮圖第二個 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

花三十秒讀完,陌生人就能知道你用什麼裝置拍照、什麼時候人在那裡,以及「那裡」的具體位置,誤差不過幾公尺。

如何在自己的機器上讀取它

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

用二十行 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 座標洩漏你的位置

只要相機 App 有定位權限,手機就會記錄 GPS,而這個預設值大多數人點過一次就忘了。把陽台、書桌或孩子學校作業的照片貼到論壇,或放上交易平台刊登,你就等於以公尺級的精度公開了自己的住址。

最著名的案例是 John McAfee。2012 年 12 月,他在逃亡途中藏身瓜地馬拉。Vice 刊登了一張用 iPhone 4S 幫他拍的照片,EXIF 資料裡有完整的 GPS 座標,任何人都能讀出他在瓜地馬拉的確切位置。幾天後,他被瓜地馬拉當局拘押。

序號把你的帳號串連起來

BodySerialNumber 和 LensSerialNumber 每台裝置獨一無二。兩個匿名帳號若貼出同一台相機拍的照片,幾乎可以確定彼此相關。研究人員正是出於這個原因爬遍照片網站,按相機序號把影像分群。你可以在網路上把不同身份分得清清楚楚,你的相機卻不做這種區分。

時間戳勾勒出你的日常

DateTimeOriginal,再加上時區偏移。單一個時間戳說明不了什麼,但一整年的上傳記錄,足以看出你幾點起床、什麼時候出門、什麼時候旅行。

縮圖會出賣你

IFD1 縮圖是詮釋資料裡一個獨立的 JPEG。從主圖裁掉一張臉或一份文件,很多編輯器根本不會去動那張原始縮圖。誰把它提取出來,誰就拿到未裁剪的原圖。2003 年,一位 TechTV 主持人貼出裁切過的個人照片,讀者從 EXIF 縮圖裡還原出完整畫面。這個教訓之所以流傳至今,是因為工具一直在犯同一個錯。

上傳之後,EXIF 在哪些地方還留著

大型社交平台(Facebook、Instagram、X)會在上傳時剝除圖片的 EXIF。除此之外的管道大多不會:電子郵件附件、論壇上傳、交易平台刊登、雲端硬碟分享連結、AirDrop,以及任何設定為傳送原始畫質的通訊軟體。只要檔案原封不動地離開你的裝置,詮釋資料就跟著一起走。

轉換格式時會發生什麼

轉換照片格式,不等於順便把詮釋資料剝掉。轉換器分兩種:

  1. 詮釋資料複製器。重新編碼、但刻意把標籤一併帶過去的工具:ExifTool、ffmpeg,以及大多數預設「保留詮釋資料」的圖形介面轉換器。用複製器把 JPEG 轉成 WebP,你的 GPS 座標會原封不動地搬進 WebP 的 EXIF chunk。
  2. 像素重編碼器。先解碼成原始像素,再用這些像素編碼出一個全新檔案的工具。輸出只含影像資料,因為詮釋資料從來就不是像素的一部分。

要手動剝除,兩種做法都只要一條指令:

# 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

這裡有一個細節要留意:方向。EXIF Orientation(標籤 0x0112)會告訴檢視器把影像旋轉,通常是 90 度。剝除標籤時如果沒有先把旋轉套用到像素上,每張直幅照片輸出後都是橫的。正確的順序是:解碼時套用方向,然後再丟掉詮釋資料。一個只剝不轉的工具,比完全不剝還糟糕。

我們的轉換器如何處理 EXIF

本站的每個轉換器都是像素重編碼器。所有工具的處理流程完全一致:

  1. 在你的瀏覽器中把來源檔案解碼成原始像素(HEIC 用 libheif 的 WebAssembly 版本,其餘格式用瀏覽器原生解碼器)。
  2. 把像素畫到 canvas 上,EXIF 方向已在解碼時一併套用。
  3. 把 canvas 編碼成目標格式。

輸出檔案裡只有壓縮後的像素,其他什麼都沒有。沒有 APP1 區段,沒有 EXIFeXIf chunk,沒有 GPS IFD,沒有序號,沒有內嵌縮圖。程式碼裡根本不存在複製詮釋資料的路徑,因為記憶體裡沒有詮釋資料可複製。而且整個過程都在用戶端執行,檔案不會離開你的裝置,所以任何伺服器也看不到原始檔。

選擇你的來源格式:

拖一個檔案進來,下載轉換後的副本,改分享它。像素完全一致,詮釋資料一乾二淨。

重點整理

  • 在 EXIF 留得下來的管道(電子郵件、論壇、交易平台、直接連結)分享照片之前,先檢查一遍。Windows 看「內容」,macOS 看「檢閱器」,Linux 用 exiftool
  • 如果檔案帶著 GPS 資料,而你寧可它不帶,那就轉換它。上面連結的每個工具都只輸出像素。
  • 如果你用不同身份分開發文,相機序號可以把它們連起來。剝除詮釋資料同樣能解決這個問題。
  • 原始檔保持原樣。EXIF 在你自己的照片庫裡確實有用,該清乾淨的是你發布出去的副本。

更多推薦閱讀