PowerScan
ZH

Canvas 指纹详解:为什么两个相同的浏览器会画出不同的像素

浏览器指纹 · 阅读约 6 分钟 · 作者:PowerScan

图片:Unsplash

Canvas 指纹是多数人听说过、却很少有人能解释清楚的技术。思路很简单:让浏览器画点东西,读回像素,再计算哈希。有意思的地方在于,这些像素为什么会在不同机器上有所不同。

绘制过程

指纹识别脚本会创建一个离屏的 <canvas>,获取 2D 上下文,并绘制一小段内容:一个填充矩形、一些用指定字体写的文字,也许还有渐变、曲线、一个表情符号。然后调用 toDataURL() 或 getImageData() 读取结果,并把这些字节计算成哈希。输出是类似 71ae464e 的短字符串。这个字符串就是“Canvas 哈希”。

绘制过程没有任何秘密,也没有向 GPU 发送页面本来说不出的内容。信息藏在渲染结果里,而不在指令里。

像素为什么不同

文字是差异的主要来源。渲染一个字形涉及实际选用的字体文件(各操作系统的备用字体不同)、字形微调和抗锯齿策略(灰度还是子像素,以及子像素的排列顺序)、光栅化器(FreeType、DirectWrite、CoreText,或浏览器自带的),以及合成是由 GPU 还是 CPU 完成的。每一项都会让边缘像素产生细微的不同。“e”边缘上的一个浅灰色像素,就足以让哈希彻底改变。

渐变和曲线还会带来更多差异:不同的图形驱动和不同的抗锯齿路径,对中间值的舍入方式不同。结果是,浏览器版本相同但 GPU、驱动或操作系统不同的两台机器,通常会产生不同的哈希,而同一台机器每次产生的哈希都相同。既稳定又有区分度,这正是追踪者想要的。

哈希告诉网站什么

单凭它,并不能说明你是谁。它只告诉网站:这个浏览器以这种方式渲染了这幅图,而这对某一批机器来说是成立的。关键在于这批机器有多大。配备集成显卡和默认字体的常见笔记本,会与许多其他机器共享同一个哈希;不常见的配置则可能接近唯一。再结合屏幕尺寸、语言列表和渲染器字符串,即便是常见的哈希,也会成为某个罕见组合的一部分。

浏览器对此做了什么

启用 resist-fingerprinting 的 Firefox 会返回空白或随机化的画布,并可能弹出画布访问提示。Brave 会给 Canvas 读取加入微小的随机扰动,使哈希在不同网站和不同会话之间变化。Safari 限制了可见的字体,并约束了一些读回操作。Chromium 本身不会随机化 Canvas;以它为基础、旨在控制指纹的浏览器是用各自的补丁来实现的,而这些补丁的质量参差不齐。

噪声不是没有代价的。每次访问都变化的 Canvas 哈希本身就是一个信号,因为真实的浏览器不会这样。对隔离的浏览器配置文件而言,更好的策略是让哈希既合理又保持一致,使它看起来像一台普通的机器,而不是每小时换一台机器。

诊断工具显示什么

PowerScan 会绘制自己的一小幅图像并显示其哈希。它从不上传该哈希;这个值只存在于你的标签页中。重新加载后哈希应当完全相同。如果不同,说明浏览器里有什么东西在注入噪声,这是在依赖该配置文件之前值得知道的。

全部文章 · 开始扫描