熵衡量指纹信号有多罕见,独立信号的比特会彼此相加,一旦超过约33比特,你在全球近80亿人中就变得独一无二;匿名集就是与你当前指纹相同的那群人。
核心要点
- 熵衡量的是"意外程度"。 一个信号只有在其取值罕见时才有追踪价值——常见取值几乎不增加区分度。
- 熵会累加。 大致独立的信号在比特数上是"相加"的,这正是为什么几个看似普通的属性组合起来也能让你变得独一无二。
- 约 33 比特 ≈ 全球唯一,因为 2 的 33 次方接近世界人口——这个阈值只是一个人口规模的近似值,并非固定不变的定律。
- 你的匿名集,就是当下与你共享同一指纹的"1 比 N"人群——它越大越安全,而追踪脚本每多读取一项罕见属性,这个人群就会缩小一分。
- 移动设备并不天然更安全。 量产手机压平了 Canvas 与 WebGL 的熵,却也补上了桌面所没有的触控与传感器信号——变的是信号构成,而不是总量。
熵究竟衡量的是什么
"熵"听起来很抽象,但背后的道理很简单:只有出人意料的信号才有信息量。 如果每个访问网站的人都用着相同的屏幕分辨率,那这个分辨率对追踪者毫无用处。而如果几乎没人和你共用同一套已安装字体组合,那这项属性几乎能把范围缩小到只剩你一人。
严格来说,某个观测值的*意外度(surprisal)*是 -log2(p) 比特,其中 p 是该取值出现的概率。一个被一半浏览器共享的值携带 1 比特的意外度(-log2(0.5) = 1);一个仅被 1024 个浏览器中的 1 个共享的值,则携带 10 比特(-log2(1/1024) = 10)。取值越罕见,贡献的比特越多——而比特正是追踪者真正在逐项收集的东西。
这也是为什么"属性数量"本身是衡量指纹风险的错误方式。十个常见属性加起来,贡献的区分度可能还不如一个罕见属性。真正重要的,是每个取值有多出人意料,而不是有多少个取值。
熵如何跨信号累加
单个信号很少能独立决定身份——参见指纹脚本能读取的完整信号列表,从 User-Agent、时区,到 Canvas 与 WebGL 输出。它们的威力来自组合。由于大致独立事件的概率是相乘的,而 log2 会把乘法变成加法,来自不同信号的熵便简单地"相加":总比特数 ≈ 各信号比特数之和。
这种可加性正是指纹识别背后的全部机制。一段 Canvas 哈希 或 WebGL 渲染器字符串,单独就可能贡献两位数的比特,因为它们同时编码了 GPU 型号、驱动版本和操作系统的渲染细节。但那些看起来平平无奇的属性同样携带比特,而脚本会在同一次读取中把它们一并收走。这些信号单独看都不算突出——危险纯粹是算术上的。
EFF 最初的 Panopticlick 研究直接测量过这一点:在约五十万个浏览器样本中,收集到的指纹分布携带约 18.1 比特的熵,意味着在该样本中,随机一个浏览器的指纹平均只会与约 286,777 个浏览器中的 1 个重合。在该数据集里,83.6% 的浏览器拥有当场唯一的指纹——在启用了 Flash 或 Java 的访客中,这一比例更高达 94.2%。逐项拆解可以看出这些比特从何而来:仅 User-Agent 字符串就携带约 10 比特,系统字体列表约 13.9 比特,浏览器插件列表约 15.4 比特;而"是否启用 Cookie"这种粗糙的信号只有区区 0.35 比特。原始数据可参阅 EFF 对 Panopticlick 结果的总结。
2010 年之后有两件事朝相反方向发展。当年数据集中信息量最大的信号——插件枚举——随着 NPAPI 插件退场已基本失效,User-Agent 字符串也被刻意冻结并精简(参见 User-Agent 精简)。但浏览器同时也长出了 Panopticlick 从未测试过的接口——音频、媒体设备、WebGL、Canvas 等等——因此把今天的完整属性集组合起来,脚本拿到的熵仍在同一量级,甚至更高。
有一点比任何单个数字都更重要:只有当信号真正彼此独立时,比特才能干净地相加,而现实中的信号并不独立。 一段 Android 的 User-Agent 就已经能推断出字体列表、屏幕几何和 GPU 字符串的大部分内容;知道其中一项,也就等于知道了其余的很多。这正是为什么 Panopticlick 各单项属性的熵加起来超过 50 比特,而整个指纹实测的联合熵只有 18.1 比特。把每个信号的比特直接相加,得到的是上界而非估计值——真实数字总会更低;看到任何工具给出的总熵值时,都该记住这一点。
匿名集:用"1 比 N"来思考
熵对研究者来说是个有用的数字,但更直观的框架是匿名集:在追踪者眼中,当下与你看起来完全一样的那群人。如果你的指纹熵为 b 比特,你的匿名集大致是"1 比 2 的 b 次方"——在 10 比特时,大约每 1024 人中有 1 人与你完全相同;在 20 比特时,约百万分之一;在 30 比特时,约十亿分之一。
这也是为什么约 33 比特是"全球唯一"的非正式阈值。世界人口约 80 亿,而 2 的 33 次方 ≈ 86 亿,一个携带 33 比特熵的指纹,其匿名集大约就是 1——也就是你自己,几乎没有其他人,这还没算上这 80 亿人里有多少人真的在上网。值得澄清这个阈值到底是什么:它是与当下世界人口挂钩的一个近似值,而非固定常数。随着全球人口增长,达到"全球唯一"所需的比特数会一点点爬升;这是一个移动的目标,只不过移动得非常缓慢。
一种常见组合——普通的 User-Agent、常见屏幕尺寸、默认字体、标准时区——可能让你落在一个数千甚至数百万人的匿名集里,这是个相当安全的位置。但只要再加上一款罕见字体、一段不寻常的 WebGL 渲染器字符串,以及一套独特的音频栈,这个人群就可能在寥寥几项额外信号之内坍缩到只剩你一人——原因还是那句话:比特是会相加的。
为什么罕见的配置对你不利
这个结论在直觉上有点反常:真正的问题在于"显得与众不同",而不是被某个单一属性追踪。 一台配备了独特高端显卡的游戏本、一种罕见的地区键盘布局、一个小众浏览器扩展——这些东西不需要任何一项单独保密,组合本身就足以让匿名集坍缩。这也是为什么建立在随机化之上的隐私工具存在一个微妙的风险:如果"被随机化"这件事本身可被检测出来,那么"这个浏览器的 Canvas 值明显是伪造的"反而可能成为一项罕见的、具有区分度的属性——具体的权衡取舍可参阅 Canvas 噪声 vs 真实哈希:随机化为何适得其反。而建立在趋同化之上的工具——比如 Tor 浏览器和 Firefox 的 resistFingerprinting——则是直接针对匿名集下手:让整个用户群体上报的比特都保持一致,而不是试图藏起其中某一项。
移动设备 vs 桌面设备:同一套数学,不同的数字
熵的分析框架是通用的,但由此得出的数字因平台而异,差异相当大。桌面 PC 拥有极其庞大的 GPU、驱动、显示器和字体组合,因此Canvas 与 WebGL 信号在桌面上往往携带较高的熵。量产手机硬件恰恰压平了这些信号——数以百万计的相同设备渲染 Canvas 和 WebGL 输出的方式完全一致,从而削弱了它们对总比特数的贡献。但移动设备也带来了桌面大多不具备的信号——屏幕几何细节、触控点数量和运动传感器——这在一定程度上抵消了前面的压平效应。综合结果是:手机的匿名集并不会自动比桌面更大,只是由高熵与低熵信号构成的组合不同罢了。具体 Android 与 iOS 设备是如何被追踪的,参见移动端浏览器指纹识别。
如何查看自己的匿名集
熵这个数字很难凭空理解——了解自己数值最快的办法,就是实际测一测。BrowserInsight 的指纹检测工具完全在客户端运行,会估算你当前配置的唯一程度,并拆解出哪些信号贡献了最多比特。EFF 的 Cover Your Tracks(Panopticlick 的继任工具)也会针对它自己聚合的数据集,给出类似的"1 比 N"数字。分别运行两者,再在启用隐私浏览器或扩展前后各测一次做对比,是判断某项防御是否真的扩大了你的匿名集最清晰的方法——因为正如上文所示,答案完全取决于它改变了哪些信号,以及改变了多少。
常见问题
熵值越高就一定越糟糕吗?
对你自身隐私而言,是的——比特越多意味着匿名集越小、浏览器越容易被识别。熵是你当前具体属性组合的一个属性,而不是一个固定分数;只要你换浏览器、更新字体,或启用某项防御,它就会变化。
删除 Cookie 会降低我的指纹熵吗?
不会。熵来自设备与浏览器特征——GPU、字体、渲染细节——这些都不是以 Cookie 形式存储的。清除 Cookie 对指纹脚本能读取到的比特没有任何影响;参见完整的指纹指南,了解为什么指纹能在数据被清除后存活,而 Cookie 却不能。
我能拥有零熵——一个彻底匿名的指纹吗?
在开放网络上做不到,但可以非常接近。那些把你的取值统一到一个庞大群体的工具(Tor 浏览器、Firefox 的 resistFingerprinting)并不是把信号藏起来,而是让所有人都上报同一套值,于是这些属性贡献的比特趋近于零。剩下的熵,来自它们无法统一的部分,比如网络层特征和时序行为。那个共享的基准值,就是在正常浏览的前提下,匿名集大小所能达到的实际上限。
为什么不同来源对"同一个"指纹给出的熵值不一样?
熵是相对于特定数据集测量出来的。EFF 的 Panopticlick 研究是针对 2010 年访问其自身网站的浏览器测量熵值;今天在另一个网站上运行的脚本,面对不同的访客群体和不同的属性列表,即便是同一台物理设备,也会算出不同的数字。比特是相对于数据集而言的,并非绝对量。


