這個神奇的 NPM 包,可一鍵生成瀏覽器指紋!
下面是兩個我們平時上網經常會遇到的場景:
場景一:在網站上瀏覽某個商品,瞭解了相關的商品信息,但並沒有下單購買,甚至沒有進行登錄操作。過兩天用同臺電腦訪問其他網站的時候卻發現很多同類商品的廣告。
場景二:在某博客中你有多個小號(水軍),這些小號的存在就是爲了刷某個帖子的熱度或者進行輿論引導,又或者純粹進行流量交易,即便你在切換賬號的時候清空了 cookie、本地緩存,重開路由器甚至使用 vpn 來進行操作,你覺得自己足夠小心,並儘可能提高水軍的真實性,但是管理人員可能還是知道這是同一個人在操作,從而被打擊。
在遇到這些場景的時候,你是不是會感到疑惑呢?或者你在研發中也要用到類似的功能?那麼你可以首先考慮一下 瀏覽器指紋
。
什麼是瀏覽器指紋
“瀏覽器指紋” 是一種通過瀏覽器對網站可見的配置和設置信息來跟蹤 Web 瀏覽器的方法,瀏覽器指紋就像我們人手上的指紋一樣,每個人擁有一份接近於獨一無二的配置。與 Cookie
和本地存儲不同,瀏覽器指紋可以做到在隱身 / 隱私模式下甚至瀏覽器數據被清除都保持不變。
怎麼生成一個瀏覽器指紋?
如果單單拿出一個配置來講可能很多人和你擁有一樣的配置,比如下面的:
-
系統版本:
-
我的系統版本是 Mac OS X 10_14_6
-
大約 11.91% 的人與我的配置相同
-
大約每 8 個人中有一個和我配置相同
-
Chrome 版本:
-
我使用的瀏覽器是 Chrome,並且版本是:81.0.4044.92
-
大約 0.08% 的人與我的配置相同
-
大約每 1250 個人中有一個和我配置相同
-
UTC+8 時間:
-
我的 UTC+8 時間是 2020.4.15 23:00:00
-
大約 2.30% 的人與我的配置相同
-
大約每 43 個人中有一個和我配置相同
如果單獨看每個配置,那他們都不能作爲你獨一無二的特徵,但是綜合起來看呢?比如就看這三項,三項的配置與你都相同的人的概率就會大大減小了。以上只是一些簡單的特徵,比如系統版本,瀏覽器版本,這些只需要一個簡單的 navigator.userAgent
屬性就可以拿到。
像這樣的屬性還有非常多個,他們可能來自 HTTP Header
、Javascript attributes
、瀏覽器插件等等,甚至還有一些和硬件相關的 API ,例如 WebGL 或者 Canvas 圖像繪製的一些 API,在繪圖時不同瀏覽器使用了不同的圖形處理引擎、不同的圖片導出選項、不同的默認壓縮級別、對抗鋸齒、次像素渲染等算法也不同,最終結果可能取決於進行計算的硬件設備。
這些屬性都組合起來那麼你就擁有了一個獨一無二的指紋。
fingerprintjs
FingerprintJS
是一個瀏覽器指紋庫,可通過查詢瀏覽器屬性並從中計算出散列的訪問者標識符,從而生成一個用戶指紋。
你可以在 https://fingerprintjs.github.io/fingerprintjs/ 查看 一個指紋 DEMO
簡單看了下源碼,發現了它主要提取了以下幾個基本能力:
-
IP 地址:部分網站訪問者通過 VPN 等方式隱藏真實網絡出口 IP,browserleaks 中提到了一種基於 WebRTC 的方案,通過發送 P2P 連接,繞過 NAT,獲取真實的出口 IP 地址;
-
聲卡信息:硬件相關參數,通過 navigator 對象的方法可以獲取,相關信息包括音頻設置和硬件特徵指紋;
-
TLS 信息:提取 web 瀏覽器的 SSL/TLS 功能,確定支持的 TLS 協議和密碼套件,並標記它們中是否有薄弱或不安全的,顯示支持的 TLS 擴展和密鑰交換組的列表。利用這些數據,它以 JA3 格式計算 TLS 指紋;
-
瀏覽器信息:目前方案提供了 Useragent 信息,容易被篡改,可結合 canvas 信息、Useragent 等信息,進行關聯判斷,識別出真正的客戶端信息及相關的版本數據。
目前瀏覽器的支持情況:
-
「Internet Explorer」 11 (see the section below)
-
「Edge」 18 and 85+
-
「Chrome」 42+
-
「Firefox」 48+
-
「Desktop Safari」 11.1+
-
「Mobile Safari」 9.3+
-
「Samsung Internet」 11.1+
-
「Android Browser」 4.1+ (see the section below)
它的使用方法也非常簡單:
通過 CDN 引用
<script>
function initFingerprintJS() {
// Initialize an agent at application startup.
const fpPromise = FingerprintJS.load()
// Get the visitor identifier when you need it.
fpPromise
.then(fp => fp.get())
.then(result => {
// This is the visitor identifier:
const visitorId = result.visitorId
console.log(visitorId)
})
}
</script>
<script
async
src="//cdn.jsdelivr.net/npm/@fingerprintjs/fingerprintjs@3/dist/fp.min.js"
onload="initFingerprintJS()"
></script>
通過 NPM 安裝
npm i @fingerprintjs/fingerprintjs
# or
yarn add @fingerprintjs/fingerprintjs
import FingerprintJS from '@fingerprintjs/fingerprintjs'
// Initialize an agent at application startup.
const fpPromise = FingerprintJS.load()
;(async () => {
// Get the visitor identifier when you need it.
const fp = await fpPromise
const result = await fp.get()
// This is the visitor identifier:
const visitorId = result.visitorId
console.log(visitorId)
})()
目前這個庫是開源的,即使用不到也可以翻翻代碼學習學習,挺有意思的~
https://github.com/fingerprintjs/fingerprintjs
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/9x1tSAOzsKZbQX1suB4VMw