如何生成浏览器端指纹

5 min read
# 技术# 追踪

有时候我们需要标识每一个接入的浏览器,以便做无状态操作的追踪,例如无状态的投票、点赞、记录访客等行为。

实现方法有很多,通常的策略是 IP + cookies。但如果用户禁用了 cookies、或隐身模式访问、或通过 VPN 访问,就难以追踪了。所以有没有更好的追踪方式?这就来研究浏览器生成指纹。

那么如何实现?


浏览器指纹依赖以下几个关键技术:

  • canvas 指纹:同一张图像可能在不同的计算机中以不同的方式渲染。有几个原因:1)在图像格式级别 – Web 浏览器使用不同的图像处理引擎,图像导出选项,压缩级别,即使最终图像是像素相同的,最终图像也可能获得不同的校验和。2)在系统级别 – 操作系统具有不同的字体,它们使用不同的算法和设置进行抗锯齿和亚像素渲染。参考
  • List of fonts:用户浏览器可使用操作系统中的字体列表。
  • 浏览器特征,例如 userAgent、webGL,webRTC 等,相当于描述一个人的体型、相貌、发色等特征。

我们要做的是尽量收集浏览器的特征信息,然后计算出一个「指纹」值,用于标识每次浏览器的访问情况。有点类似 Duck typing 的判断机制。

Duck typing:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”


虽然两个完全一致的硬件设备信息 && 个人喜好设置的浏览器指纹出现概率应该很低,但是依然有重复的可能。那么由浏览器生成的指纹的准确率会是多少?

目前能找到的指纹生成工具 fingerprintjs2 号称识别准确率为 99.5%,就是说每 1000 个浏览器会出现 5 个产生相同指纹的。

这个准确率对于我来说足够了。

例如本博客的 BlogHelper 模块提供的无状态「访客量」和「like」服务就是基于上述技术实现的,99.5%的识别率是完全可以接受的(毕竟访问量比较低)。


最后来了解下浏览器特征的“相似率”,可以访问 amiunique 查看各个浏览器特征的相似率(Similarity ratio)。本文写下时这个工具已经积累了 1,621,684 条记录。

这些认知对如何设置 fingerprintjs2 的生成策略有一定的帮助。

以下为本次测试的浏览器(Chrome Version 79)的结果,摘出几项值得关注的指标:

Attribute Similarity ratio Type Desc
User agent 0.12% 硬件信息 代理用户请求的浏览器信息
Content language Unique 0% 用户配置 浏览器期望服务端返回的语言
Canvas 0.14% 硬件信息 通过 canvas 追踪
List of fonts (JS) 0.03% 用户配置 通过检测用户可使用的系统字体

参考