Canvas 指紋說明:為什麼兩個相同的瀏覽器畫出不同的像素

Canvas 指紋是多數人聽過、卻最少人能解釋清楚的技術。概念很簡單:要求瀏覽器畫出某些東西,讀回像素,然後計算雜湊值。有趣的是,不同機器的像素為什麼會不一樣。
繪製內容
指紋辨識指令碼會建立一個螢幕外的 <canvas>,取得 2D 繪圖環境,並畫出一小段序列:一個填滿的矩形、一些指定字型的文字,也許再加上漸層、曲線、表情符號。接著它呼叫 toDataURL() 或 getImageData() 讀取結果,再把這些位元組送進雜湊函式。輸出是一個簡短的字串,例如 71ae464e。這個字串就是「canvas 雜湊值」。
繪製的過程沒有任何祕密,也沒有任何頁面無法自行描述的內容被送到 GPU。資訊存在於轉譯結果中,而不是指令裡。
為什麼像素會不同
文字是變化的主要來源。轉譯一個字形,牽涉到實際被選用的字型檔(備用字型因作業系統而異)、微調與反鋸齒策略(灰階或次像素,以及次像素的排列順序)、點陣化引擎(FreeType、DirectWrite、CoreText,或瀏覽器自己的),以及合成工作是由 GPU 還是 CPU 完成。這些因素各自都會產生略有不同的邊緣像素。「e」邊緣上一個淺灰色像素,就足以讓雜湊值完全改變。
漸層和曲線會增加更多變化:不同的顯示卡驅動程式與不同的反鋸齒路徑,會用不同方式對中間值進行捨入。結果是,瀏覽器版本相同、但 GPU、驅動程式或作業系統不同的兩台機器,通常會產生不同的雜湊值,而同一台機器每次都會產生相同的雜湊值。穩定而多樣,正是追蹤者想要的。
雜湊值能告訴網站什麼
就它本身而言,完全無法說明你是誰。它只告訴網站,這個瀏覽器會以這種方式轉譯這段繪製內容,而這對某一群機器來說都是成立的。重點在於這個群體有多大。一台使用內建顯示晶片和預設字型的常見筆電,會與許多其他機器共用同一個雜湊值。不尋常的配置則可能接近唯一。再加上螢幕尺寸、語言清單和轉譯器字串,即使是常見的雜湊值,也會成為一組稀有組合的一部分。
瀏覽器對此做了什麼
啟用 resist-fingerprinting 的 Firefox 會回傳空白或隨機化的 canvas,並可能提示是否允許存取 canvas。Brave 會對 canvas 讀取加入微小的隨機擾動,讓雜湊值隨網站和工作階段而變。Safari 限制了可見的字型,並約束部分讀回操作。Chromium 本身不會將 canvas 隨機化;以它為基礎、目標是控制指紋的瀏覽器,會用自己的修補來達成,而這些修補的品質參差不齊。
雜訊不是沒有代價的。每次造訪都改變的 canvas 雜湊值本身就是一種訊號,因為真正的瀏覽器不會這樣。對隔離的瀏覽器設定檔來說,更好的策略是一個合理且一致的雜湊值,讓它看起來像是一台普通的機器,而不是每個小時就換一台不同的機器。
診斷工具顯示什麼
PowerScan 會畫出自己的小圖片並顯示雜湊值。它絕不會上傳這個值;該值只存在於你的分頁中。重新載入後,雜湊值應該完全相同。如果不同,就表示瀏覽器中有東西在注入雜訊,在你依賴那個設定檔之前,值得先知道這件事。


