指纹、追踪与隐私
5.1 当 Cookie 不够用了
5.1.1 Cookie 的局限
上一章我们讲了第三方 Cookie 如何被用于跨站追踪。但 Cookie 有一个"致命缺陷"(对追踪者来说):用户可以删除它。
- 清除浏览器数据 → Cookie 消失
- 使用隐私模式 → Cookie 不会被保存
- Safari/Firefox 默认阻止第三方 Cookie → 追踪失效
- 安装广告拦截器 → 追踪脚本被阻止
广告行业需要一种更"持久"的追踪方式——即使用户清除了所有 Cookie、使用了隐私模式,依然能识别出"这是同一个人"。
这就是浏览器指纹(Browser Fingerprinting)。
5.1.3 指纹追踪 vs Cookie 追踪的本质区别
Cookie 追踪是"主动标记"——服务器给你贴一个标签,下次见到这个标签就认出你。你可以撕掉标签(删除 Cookie)。
指纹追踪是"被动识别"——不需要给你贴任何标签,只需要观察你的"长相"(设备特征)就能认出你。你不能改变自己的"长相"(除非换设备)。
Cookie 追踪(主动标记):
服务器: "给你贴个标签 #12345"
浏览器: [存储标签]
下次访问: "我看到标签 #12345 了,是你!"
用户清除 Cookie: "标签没了,我不认识你了"
指纹追踪(被动识别):
服务器: "让我看看你的特征..."
服务器: "1920×1080 + RTX 4060 + 23种字体 + Chrome 125..."
服务器: "这个组合我见过,是你!"
用户清除 Cookie: "没用,你的特征没变,我还是认识你"
5.1.2 什么是浏览器指纹
浏览器指纹的原理很简单:你的浏览器在访问网页时,会暴露大量关于你设备的信息。把这些信息组合起来,就能生成一个几乎唯一的标识符——就像人的指纹一样。
单独看每一项信息都不足以识别你:
- 屏幕分辨率是 1920×1080?全世界有几亿人都是这个分辨率。
- 操作系统是 Windows 11?几亿人。
- 浏览器是 Chrome 125?几千万人。
- 时区是 UTC+8?十几亿人。
但当你把几十项这样的信息组合起来:
- 1920×1080 + Windows 11 + Chrome 125 + UTC+8 + 安装了 23 种字体 + GPU 是 NVIDIA RTX 4060 + 语言是 zh-CN + 有 3 个浏览器插件 + Canvas 渲染哈希是
a7f3b2c1+ WebGL 渲染哈希是d4e5f6a7+ AudioContext 指纹是b8c9d0e1+ ...
这个组合在全球可能只有你一个人匹配。研究表明,浏览器指纹通常有超过 30 比特的熵(entropy),这意味着它可以在超过 10 亿人中唯一识别一个用户。
5.2 指纹采集的技术手段
5.2.1 基础信息:你的浏览器在"自我介绍"
网站可以通过 JavaScript 轻松获取大量关于你设备的信息——不需要任何权限,不会弹出任何提示:
const fingerprint = {
// 屏幕信息
screenWidth: screen.width, // 1920
screenHeight: screen.height, // 1080
colorDepth: screen.colorDepth, // 24
devicePixelRatio: window.devicePixelRatio, // 1.5
// 浏览器信息
userAgent: navigator.userAgent, // "Mozilla/5.0 (Windows NT 10.0..."
language: navigator.language, // "zh-CN"
languages: navigator.languages, // ["zh-CN", "zh", "en"]
platform: navigator.platform, // "Win32"
hardwareConcurrency: navigator.hardwareConcurrency, // 8 (CPU 核心数)
deviceMemory: navigator.deviceMemory, // 8 (内存 GB 数)
// 时间信息
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, // "Asia/Shanghai"
timezoneOffset: new Date().getTimezoneOffset(), // -480
// 触控支持
touchSupport: navigator.maxTouchPoints, // 0 (桌面) 或 10 (触屏)
};
这些信息为什么能识别你? 单独看每一项都很普通——很多人的屏幕都是 1920×1080。但组合起来就不一样了:1920×1080 + 24 位色深 + 1.5 倍缩放 + 中文 + 8 核 CPU + 8GB 内存 + 亚洲/上海时区 + 无触屏——这个组合可能只有几千人符合。再加上后面的 Canvas、WebGL 等信息,就能缩小到几乎唯一。
这些信息本来是浏览器正常工作需要暴露的——网页需要知道屏幕大小来做响应式布局,需要知道语言来显示正确的内容。但它们被追踪者"借用"了。
5.2.2 Canvas 指纹:让你的 GPU "签名"
Canvas 指纹是最强大的指纹技术之一。原理是:让浏览器在一个隐藏的画布上绘制特定的图形和文字,然后读取渲染结果的像素数据。
function getCanvasFingerprint() {
// 创建一个隐藏的画布(用户看不见)
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 50;
const ctx = canvas.getContext('2d');
// 绘制一些文字和图形
ctx.textBaseline = 'top';
ctx.font = '14px Arial';
ctx.fillStyle = '#f60';
ctx.fillRect(0, 0, 200, 50); // 画一个橙色矩形
ctx.fillStyle = '#069';
ctx.fillText('Browser Fingerprint 🖐️', 2, 15); // 写一行字
// 画一个半透明的绿色圆
ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
ctx.beginPath();
ctx.arc(50, 30, 10, 0, Math.PI * 2);
ctx.fill();
// 把画布内容导出为像素数据,生成哈希值
const dataURL = canvas.toDataURL();
return hashFunction(dataURL);
}
关键问题:同样的绘制指令,为什么不同设备画出来的不一样?
因为"画一个字"这件事,底层涉及大量硬件和软件的差异:
- GPU 不同:NVIDIA 和 AMD 的抗锯齿算法不一样,像素边缘的处理方式有微小差异
- 操作系统不同:Windows 用 DirectWrite 渲染字体,macOS 用 Core Text,同一个"Arial"字体在两个系统上的像素输出不完全一致
- 字体版本不同:同一个字体的不同版本,字形可能有 0.1 像素的差异
- 显卡驱动不同:不同版本的驱动对颜色混合的计算精度不同
这些差异肉眼完全看不出来——两台电脑上画出来的图看起来一模一样。但把像素数据导出来做哈希,得到的值就是不同的。这就是你的 GPU 的"签名"。
5.2.3 WebGL 指纹:直接暴露你的显卡型号
WebGL 是浏览器里的 3D 图形接口。它能做的事情比 Canvas 更多——包括直接读取你的 GPU 型号:
function getWebGLFingerprint() {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
// 这个扩展能直接读取 GPU 信息
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
// UNMASKED_VENDOR_WEBGL: GPU 厂商
const vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
// 例如: "NVIDIA Corporation"
// UNMASKED_RENDERER_WEBGL: GPU 具体型号
const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
// 例如: "NVIDIA GeForce RTX 4060/PCIe/SSE2"
// 你的 GPU 还支持哪些 3D 功能
const extensions = gl.getSupportedExtensions();
// 返回一个列表,不同 GPU 支持的扩展不同
return { vendor, renderer, extensions };
}
为什么这个很强? 因为 "RTX 4060 + 特定驱动版本 + 特定扩展列表" 这个组合非常独特。GPU 型号有几百种,驱动版本有几十种,扩展组合更是千变万化。光这一项就能把你从几百万人中缩小到几千人。
而且这个信息是硬件决定的——你换浏览器、清 Cookie、开无痕模式,GPU 型号都不会变。
5.2.4 AudioContext 指纹:连声卡都不放过
音频处理也能产生指纹。原理是:生成一段音频信号,分析你的声卡处理后的输出:
function getAudioFingerprint() {
// 创建一个音频处理环境
const audioCtx = new AudioContext();
// 创建一个音频信号源(三角波,10000Hz)
const oscillator = audioCtx.createOscillator();
oscillator.type = 'triangle';
oscillator.frequency.value = 10000;
// 创建一个分析器,用来读取处理后的频谱数据
const analyser = audioCtx.createAnalyser();
// 静音——用户完全听不到任何声音
const gain = audioCtx.createGain();
gain.gain.value = 0;
// 连接:信号源 → 分析器 → 静音 → 输出
oscillator.connect(analyser);
analyser.connect(gain);
gain.connect(audioCtx.destination);
// 不同设备的音频处理芯片对同一个信号的处理结果有微小差异
// 这些差异可以被分析器检测到,形成指纹
}
原理:不同的声卡芯片、不同的音频驱动、不同的操作系统音频栈,对同一个数字信号的处理方式有微小的数值差异(比如浮点精度不同)。这些差异人耳听不出来,但代码能检测到。
5.2.5 字体指纹:你装了什么字体
通过检测你的系统安装了哪些字体来识别你:
function detectFonts() {
const testFonts = [
'Arial', 'Verdana', 'Times New Roman', 'Courier New',
'Georgia', 'Comic Sans MS', 'Impact', 'Lucida Console',
'微软雅黑', '宋体', '黑体',
// ... 测试几百种字体
];
const testString = 'mmmmmmmmmmlli'; // 用这些字符测试宽度
const span = document.createElement('span');
span.style.fontSize = '72px';
span.textContent = testString;
document.body.appendChild(span);
const detected = [];
for (const font of testFonts) {
// 设置字体为"目标字体 + 后备字体"
span.style.fontFamily = `'${font}', monospace`;
const width = span.offsetWidth;
// 如果渲染宽度和纯 monospace 不同,说明目标字体存在
// (因为浏览器用了目标字体来渲染,字形宽度不同)
if (width !== baseMonospaceWidth) {
detected.push(font);
}
}
return detected; // 例如: ["Arial", "微软雅黑", "宋体", ...]
}
原理:浏览器渲染文字时,如果指定的字体存在就用它,不存在就用后备字体。不同字体的同一个字符宽度不同。所以通过测量渲染宽度,就能判断某个字体是否安装了。
为什么有效? 设计师可能装了几百种字体,程序员可能装了各种等宽字体(Fira Code、JetBrains Mono),普通用户只有系统默认的几十种。你的字体列表就像你的"软件指纹"——反映了你的职业和使用习惯。
5.3 指纹的威力:为什么它比 Cookie 更可怕
5.3.1 Cookie vs 指纹对比
| 特性 | Cookie | 浏览器指纹 |
|---|---|---|
| 用户可见 | ✓(可在设置中查看) | ✗(完全隐形) |
| 用户可删除 | ✓ | ✗(无法"删除"你的硬件配置) |
| 隐私模式有效 | ✓(不保存 Cookie) | ✗(指纹不变) |
| 需要存储 | ✓(存在浏览器中) | ✗(无状态,每次实时计算) |
| 法律要求同意 | ✓(GDPR) | 理论上需要,但难以执行 |
| 跨浏览器追踪 | ✗ | 部分可以(如果硬件相同) |
指纹追踪最可怕的地方在于:你无法感知它的存在,也无法通过简单的操作消除它。清除 Cookie 是一键的事,但你不能"清除"你的 GPU 型号或屏幕分辨率。
5.3.2 指纹追踪的规模
2025 年约翰霍普金斯大学和德州农工大学的联合研究发现,大量网站在秘密使用浏览器指纹追踪用户。这些追踪脚本通常伪装成正常的网页功能代码,很难被检测到。
2026 年 4 月,The Register 报道指出 Chrome 浏览器缺乏任何有效的指纹防御机制——至少有 30 种不同的指纹技术可以在 Chrome 中正常工作。相比之下,Brave 和 Firefox 都实现了不同程度的指纹防护。
5.3.3 合法用途
指纹技术不全是邪恶的。它也有合法用途:
- 反欺诈:银行用指纹检测异常登录("这个设备从未登录过你的账户")
- 反机器人:区分真实用户和自动化脚本
- 设备认证:作为多因素认证的一部分
- 许可证管理:软件绑定到特定设备
问题不在于技术本身,而在于它被用于未经用户同意的追踪。
5.4 指纹浏览器:反向利用指纹技术
5.4.1 什么是指纹浏览器
"指纹浏览器"(Antidetect Browser)是一类特殊的浏览器工具,它的作用是伪造浏览器指纹——让同一台电脑上的多个浏览器实例看起来像是来自完全不同的设备。
常见的指纹浏览器有:Multilogin、GoLogin、AdsPower、Dolphin Anty 等。
5.4.2 工作原理
普通浏览器:
┌─────────────────────────────────┐
│ 你的真实设备 │
│ GPU: RTX 4060 │
│ 屏幕: 1920×1080 │
│ 字体: 45 种 │
│ → 指纹: #A7F3B2C1 │
└─────────────────────────────────┘
无论开多少个窗口,指纹都是 #A7F3B2C1
指纹浏览器:
┌─────────────────────────────────┐
│ Profile 1(伪装) │
│ GPU: Intel UHD 630(伪造) │
│ 屏幕: 1366×768(伪造) │
│ 字体: 32 种(伪造) │
│ → 指纹: #D4E5F6A7 │
├─────────────────────────────────┤
│ Profile 2(伪装) │
│ GPU: AMD RX 580(伪造) │
│ 屏幕: 2560×1440(伪造) │
│ 字体: 67 种(伪造) │
│ → 指纹: #B8C9D0E1 │
├─────────────────────────────────┤
│ Profile 3(伪装) │
│ GPU: Apple M1(伪造) │
│ 屏幕: 2560×1600(伪造) │
│ 字体: 28 种(伪造) │
│ → 指纹: #F1E2D3C4 │
└─────────────────────────────────┘
每个 Profile 看起来像完全不同的设备
5.4.3 使用场景
指纹浏览器的用户群体比较特殊:
灰色地带的用途:
- 多账号运营:在电商平台(Amazon、eBay)或社交媒体上运营多个账号,避免被平台检测到"同一个人"
- 广告投放:广告从业者需要多个账号来测试不同的广告策略
- 价格比较:某些网站会根据你的浏览历史显示不同价格,指纹浏览器可以绕过这种"杀熟"
明确违规的用途:
- 刷单、刷评论
- 薅羊毛(注册多个新用户领优惠)
- 规避平台封禁
合法用途:
- 隐私保护(不想被追踪的普通用户)
- 安全研究和渗透测试
- 新闻记者保护信源
5.4.4 指纹浏览器 vs 隐私浏览器
需要区分两个概念:
- 隐私浏览器(如 Brave、Firefox、Tor Browser):目标是保护你的隐私,让追踪者无法识别你。它们通过统一化或随机化指纹来实现。
- 指纹浏览器(如 Multilogin、GoLogin):目标是让你看起来像多个不同的人。它们通过伪造逼真的指纹来实现。
前者是防御性的,后者是进攻性的。
5.5 隐私浏览器对比
5.5.1 各浏览器的隐私防护策略
不同浏览器对指纹追踪采取了不同的防御策略:
Chrome:几乎不防护
截至 2026 年,Chrome 没有内置任何有效的指纹防护机制。Google 的立场是通过 Privacy Sandbox 提供"隐私保护的广告",而不是阻止追踪本身。考虑到 Google 的广告业务,这不难理解。
Firefox:增强型追踪保护(ETP)
Firefox 的策略是"已知追踪者阻止":
- 默认阻止已知的第三方追踪 Cookie
- 阻止已知的指纹采集脚本(基于 Disconnect 的追踪者列表)
- 提供
privacy.resistFingerprinting选项(需手动开启),开启后会:- 统一报告时区为 UTC
- 统一报告屏幕分辨率为窗口大小
- 禁用某些字体枚举 API
- 返回统一的 Canvas 和 WebGL 数据
Firefox 的 about:config 中:
privacy.resistFingerprinting = true // 开启后大幅降低指纹唯一性
privacy.trackingprotection.fingerprinting.enabled = true
Brave:随机化策略
Brave 采用了一种独特的方法——指纹随机化:
- 不是阻止网站获取指纹信息(这会破坏网站功能)
- 而是每次返回略微不同的随机值
- Canvas 渲染结果每次都有微小的随机噪声
- WebGL 数据被轻微扰动
- 字体列表被随机化
这意味着追踪者每次获取的指纹都不同,无法将多次访问关联到同一个用户。
Brave 的指纹防护效果:
第一次访问: 指纹 = #A1B2C3D4
第二次访问: 指纹 = #E5F6A7B8 ← 不同!
第三次访问: 指纹 = #C9D0E1F2 ← 又不同!
追踪者无法确定这是同一个人
Tor Browser:统一化策略
Tor Browser 采用最极端的方法——让所有用户看起来一模一样:
- 所有 Tor 用户报告相同的屏幕分辨率(初始窗口大小)
- 所有用户报告相同的字体列表
- 所有用户报告相同的时区(UTC)
- 禁用 WebGL
- Canvas 返回空白数据
- 加上 Tor 网络的 IP 匿名化
代价是:很多网站功能受限,浏览体验较差。
5.5.2 隐私浏览器推荐
| 浏览器 | 引擎 | 指纹防护 | 广告拦截 | 易用性 | 适合人群 |
|---|---|---|---|---|---|
| Brave | Chromium | 强(随机化) | 内置 | 高 | 想要隐私但不想折腾的人 |
| Firefox | Gecko | 中(需配置) | 需装扩展 | 中 | 愿意花时间配置的人 |
| Tor Browser | Gecko | 极强(统一化) | 内置 | 低 | 需要极端匿名的人 |
| Safari | WebKit | 中(ITP) | 需装扩展 | 高 | Apple 生态用户 |
| Mullvad Browser | Gecko | 强(类 Tor) | 内置 | 中 | 不需要 Tor 网络但想要 Tor 级隐私 |
对于大多数人,Brave 是最好的平衡点:它基于 Chromium(兼容性好、Chrome 扩展都能用),默认就有强大的隐私保护,不需要任何配置。
如果你更在意引擎多样性和开源理念,Firefox + uBlock Origin + 隐私设置调优 是另一个好选择。
5.6 说实话,普通人能做什么
5.6.1 先承认一个现实
前面讲了这么多追踪技术,你可能在想:"那我该怎么办?"
网上很多隐私指南上来就说"换 Brave"、"装 Firefox"、"用 Tor"。但说实话,对大多数人来说这些建议不现实:
换浏览器? Chrome 里的书签、密码、扩展、登录状态、同步数据——迁移成本太高了。而且很多人的工作流依赖 Chrome 的特定功能或扩展,换了就没法用。100 个人里可能找不到 1 个愿意为了"隐私"放弃这些便利。
装隐私插件? 有门槛。而且一个插件负责决定"要不要拦截这个请求",它本身就需要读取你所有的浏览数据——把隐私决策交给一个插件,这件事本身就有点讽刺。你怎么确定这个插件不收集你的数据?
完全拒绝追踪? 不可能。指纹追踪是无感的,你没有"拒绝"的按钮。
所以现实是:大多数人会继续用 Chrome,不会装什么特殊插件,也不会做什么复杂配置。在这个前提下,能做什么?
5.6.2 零成本的事情(不需要换浏览器、不需要装插件)
这些是你现在就能做的,不改变任何习惯:
Cookie 弹窗直接点"拒绝全部":第四章讲过了,不影响网站功能,只是拒绝被追踪。
Chrome 设置里关闭"广告主题":设置 → 隐私和安全 → 广告隐私 → 把"广告主题"、"网站建议的广告"、"广告效果衡量"全部关掉。这是 Chrome 自带的追踪功能,关掉不影响任何网站使用。
不要用 Google 账号登录第三方网站:很多网站提供"用 Google 登录"的选项。方便是方便,但这让 Google 知道你在哪些网站有账号。能用邮箱注册就用邮箱。tips
偶尔用无痕模式:搜索敏感内容、访问不常去的网站时,开个无痕窗口。不能防指纹,但至少不留 Cookie 和历史记录。
5.6.3 低成本的事情(稍微花点时间)
如果你愿意花 5 分钟做一次性设置:
Chrome 设置里阻止第三方 Cookie:设置 → 隐私和安全 → 第三方 Cookie → 选择"阻止第三方 Cookie"。这一个设置就能干掉大部分跨站追踪,而且几乎不影响网站功能(极少数网站可能需要你手动允许)。
安装 uBlock Origin(如果你愿意装一个插件的话):这是最受信任的广告拦截器,开源、无商业利益、不收集数据。它不仅拦截广告,也拦截大量追踪脚本。Firefox 版功能最完整,Chrome 版因为 Manifest V3 限制稍弱但仍然有用。
检查一下你的指纹唯一性:访问
coveryourtracks.eff.org(EFF 的工具),它会告诉你你的浏览器指纹有多独特。看看结果,心里有个数。
5.6.4 接受不完美
最后说一句大实话:完美的隐私保护在 2026 年是不存在的。
即使你做了上面所有事情,Google 仍然通过你的 Google 账号知道你搜索了什么、看了什么 YouTube 视频、去了什么地方(如果你用 Google Maps)。你的手机运营商知道你的位置。你的 ISP 知道你访问了哪些网站。
隐私保护不是"全有或全无"的事情。它是一个光谱——你在方便和隐私之间找到自己舒服的平衡点就行。有些人愿意为了隐私放弃便利(用 Tor、不用智能手机),有些人觉得"被追踪就被追踪吧,反正我也没什么秘密"。大多数人在中间——稍微注意一下,但不至于影响正常生活。
关掉 Chrome 的广告追踪设置、Cookie 弹窗点拒绝、不用 Google 登录乱七八糟的网站——做到这三点,你已经比 90% 的人更注意隐私了。不需要焦虑。
5.7 隐私的未来
5.7.1 技术军备竞赛
隐私保护和追踪技术之间是一场永无止境的军备竞赛:
追踪者发明 Cookie → 用户清除 Cookie
追踪者发明第三方 Cookie → 浏览器阻止第三方 Cookie
追踪者发明指纹追踪 → 浏览器随机化指纹
追踪者发明 CNAME 伪装 → 浏览器检测 CNAME 追踪
追踪者发明服务器端追踪 → 监管、审计与更严格的第一方数据治理
每当一种追踪技术被防御,追踪者就会发明新的技术。这场竞赛不会结束。
5.7.2 服务器端追踪:下一个战场
最新的趋势是"服务器端追踪"——追踪逻辑从浏览器端转移到服务器端。比如:
- 网站在自己的服务器上运行 Google Analytics,而不是在浏览器中加载 GA 脚本
- 追踪数据通过第一方域名发送,广告拦截器无法区分它和正常的网站请求
这种方式对用户来说几乎不可见,也很难被浏览器端的工具拦截。
5.7.3 立法是最终答案吗
技术手段有其局限性。最终,隐私保护可能需要依赖法律:
- GDPR(欧盟):要求数据处理必须有合法基础,用户有权拒绝
- CCPA/CPRA(加州):给予用户"不要出售我的个人信息"的权利
- 中国个人信息保护法:2021 年生效,对个人信息处理有严格要求
但法律的执行力度和技术的发展速度之间总是有差距。在法律完善之前,技术自卫仍然是必要的。
5.7.4 一个思想实验
想象一下:如果你走在街上,每经过一家商店,商店的摄像头都会扫描你的脸,记录你的身高、体重、穿着、步态,然后把这些信息卖给广告公司。你会接受吗?
大多数人会说"不"。但这正是浏览器指纹在网上做的事情——只不过扫描的不是你的脸,而是你的设备特征。
线上和线下的隐私标准不应该有双重标准。如果我们不接受线下的无差别监控,我们也不应该接受线上的无差别追踪。
5.7.5 隐私不是"我没做坏事所以不怕"
一个常见的误解是:"我又没做什么见不得人的事,为什么要在意隐私?"
这个逻辑的问题在于:
隐私是一种权力关系:当别人知道你的一切而你对他们一无所知时,你处于弱势。这种信息不对称可以被用来操纵你(精准广告就是一种温和的操纵)。
"坏事"的定义会变:今天合法的事情明天可能变成敏感的。你的浏览历史是永久的,但社会规范是变化的。
数据泄露是常态:即使你信任某家公司,它的数据库也可能被黑客攻破。你的数据越少被收集,泄露时的风险就越小。
隐私是集体权利:即使你个人不在意,大规模的数据收集会影响整个社会——它使得大规模监控、社会信用系统、选举操纵成为可能。
隐私不是"有什么要隐藏的",而是"有什么要保护的"。
下一章,我们从技术和隐私的话题中跳出来,看看浏览器背后的公司——它们为什么要做浏览器,浏览器怎么赚钱,以及为什么"免费"的浏览器其实是最赚钱的生意。