如何生成浏览器端指纹

5 min read
# 技术# 追踪
View

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

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


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

  • canvas 指纹:同一张图像可能在不同的计算机中以不同的方式渲染。有几个原因:

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

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


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

目前能找到的指纹生成工具 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% 用户配置 通过检测用户可使用的系统字体

参考