浏览器指纹是什么
不用 cookie,网站也能认出你:把几十个浏览器属性拼起来做个哈希,就是一枚指纹。这篇文章讲它的原理、熵为什么会叠加、指纹和 cookie 的区别,以及本站"指纹真实性"评分背后的思路。
6 分钟阅读 · 发布于 2026年9月10日
清掉 cookie、开无痕窗口、换个 IP,然后发现某个网站还是知道你是谁——这背后多半是浏览器指纹。它不往你电脑里存任何东西,只是把浏览器主动暴露的一堆信息收集起来,算一个哈希。单看每一项都很普通,合在一起却常常是独一无二的。
网站是怎么在没有 cookie 的情况下认出你的
打开任何一个网页,浏览器都会告诉服务器一大堆事:User-Agent 字符串、Accept-Language、屏幕分辨率和色深、时区、装了哪些字体、支持哪些编解码器、CPU 核心数、内存大概多少、有没有触摸屏。这些都是正当的 API,本来是给网页做适配用的。
再往深一层,网页可以让浏览器"干点活"然后看结果。让它用 canvas 画一段文字和几个图形,导出像素数据;让它用 WebGL 渲染一个三角形,顺便问一下显卡型号;让它用 Web Audio 生成一段音频信号,读回波形。这些结果取决于你的显卡、驱动、操作系统的字体渲染方式、浏览器版本,甚至系统里有没有装某个字体。不同机器算出来的像素会有微小差别,这些差别经过哈希之后就成了稳定的标识。
把上面几十项按固定顺序拼成一个字符串,做一次 SHA-256,得到的就是你的"访客 ID"。本站指纹页面上的 Visitor ID 就是这么来的。
熵:为什么普通属性叠起来就不普通了
信息论里用"熵"衡量一个属性能把人群分得多细。一个属性如果一半人是 A、一半人是 B,它提供 1 比特信息;如果一千个人里只有一个和你一样,它提供大约 10 比特。要在几十亿人里唯一地认出一个人,理论上需要三十多比特。
单个属性离这个数很远。1920×1080 的屏幕太常见了,Chrome 也是,zh-CN 的语言设置在中文用户里更是毫无区分度。但熵是可以叠加的——只要属性之间相关性不强。屏幕分辨率、时区、语言三项合起来也许只有几比特,再叠上你的字体列表(装了 Adobe 全家桶和几个特殊中文字体的人不多)、WebGL 渲染器的完整名称(型号加驱动版本)、canvas 哈希,就很容易跨过唯一的门槛。
EFF 的 Panopticlick 项目(现在叫 Cover Your Tracks)就是在做这件事:收集自愿参与者的指纹,统计每一项的分布,然后告诉你"在我们看到的浏览器里,有多少比例和你的这一项相同"。本站指纹页底部的"唯一性"统计也是同样的思路,只是样本是本站的访客。数字越小,那一项越能暴露你。
指纹和 cookie 的区别
Cookie 是网站放在你浏览器里的一张纸条,你随时可以撕掉。指纹不同:
- 它不需要在你这边存任何东西,所以没有"清除"这个操作。
- 它天然跨站。只要两个网站用同一套脚本、同一套哈希算法,得到的 ID 就一样。
- 无痕模式对它几乎无效,因为无痕只隔离存储,不改变你的硬件和字体。
指纹也有弱点。浏览器一升级,canvas 渲染可能变了;换个显示器,分辨率变了;装了一个新字体,字体列表变了。所以指纹会"漂移",追踪者不能只做精确匹配,得做模糊匹配——比如允许一两项变化、看剩下的项目是否吻合。所以对追踪者最值钱的,是那些熵高又稳定的属性,比如显卡型号、音频哈希。
"指纹真实性"评分是怎么想的
指纹页面顶部有一个大数字,叫"指纹真实性"。它不是在评价你的隐私好不好,而是在回答另一个问题:这个浏览器看起来像一个真实的、普通的浏览器吗,还是像一个被改过的环境?
评分从 100 开始,每发现一处矛盾就扣分:
| 检查项 | 扣分 |
|---|---|
HTTP 头里的 User-Agent 和 JS 里的 navigator.userAgent 不一致 |
30 |
| 内核特性和 UA 声称的浏览器矛盾(UA 说 Chrome,行为像 Firefox) | 25 |
| Client Hints 的平台或品牌与 UA 矛盾 | 15 |
| IP 推断的时区 ≠ JS 时区 | 15 |
| JS 时钟与 IP 时区的时间相差超过 3 分钟 | 5 |
Accept-Language 的首选语言 ≠ navigator.language |
10 |
| WebRTC 暴露的公网 IP ≠ HTTP 连接的 IP | 15 |
navigator.webdriver 为真或有无头浏览器痕迹 |
30 |
| 屏幕参数不可能(可用宽度大于总宽度之类) | 10 |
| 桌面 UA 却用软件渲染器(SwiftShader、llvmpipe) | 10 |
| Chrome 桌面版插件数为 0 | 5 |
| canvas 两次绘制结果不同(有噪声扩展) | 10 |
注意这里没有一项是"你的指纹太独特"。评分关心的是一致性。原因很实际:反欺诈系统和风控系统也是这么想的。一个各项都正常、互相吻合的普通浏览器,在人群里并不显眼;一个把 UA 改成 Windows、时区改成纽约、但 WebGL 渲染器还是 Apple M2、Accept-Language 还是 zh-CN 的浏览器,反而会立刻被标记。伪装每一项而不让它们互相打架,比不伪装难得多。
所以这个评分对两类人有用。用翻墙工具的人可以拿它检查有没有露馅——最常见的是 IP 时区和系统时区对不上,以及 WebRTC 漏出真实 IP。用反检测浏览器的人可以拿它检查伪装是否自洽。详细的检查项各有一篇文章:时区与语言一致性、WebRTC 泄漏、Bot 检测。
本站怎么处理你的数据
指纹实验室只存哈希和粗粒度属性:canvas、WebGL、音频、字体的哈希值,浏览器家族、操作系统家族、屏幕尺寸、时区、语言、渲染器名称这些用来做唯一性统计的项目。原始的 canvas 像素、音频波形、IP 地址都不会入库。页面上有一个"参与统计"的选项,取消勾选就什么都不上传,只在本地显示结果。
常见问题
指纹能不能完全避免? 很难。Tor Browser 的策略是让所有用户看起来一模一样(固定窗口尺寸、禁用大部分 API),代价是网页体验很差。普通浏览器里能做的是减少高熵项:别装太多字体、用主流分辨率、开启 Firefox 的"抵御指纹追踪"之类的功能。
用扩展给 canvas 加噪声有用吗? 它让每次哈希都不同,确实破坏了精确匹配,但也让你成为"canvas 结果会变的那一小撮人",这本身就是一个特征。本站的评分会为此扣 10 分。详见 Canvas、WebGL 与音频指纹。
为什么同一台电脑上 Chrome 和 Firefox 的指纹不一样? 因为渲染引擎、字体回退策略、音频处理管线都不同。指纹识别的是"这个浏览器在这台机器上",不是这台机器本身。