返回知识中心
指纹

performance.now:计时器精度与浏览器指纹

performance.now 的精度与抖动暴露计时器降精度、时钟偏移和调度负载。在对比两个浏览器构建之前,先把它们测出来。

BotBrowser Team

文档中心

想直接看维护中的产品文档?

这篇文章对应的主题已经有文档中心页面。需要规范流程、当前参数和长期参考时,优先看 docs。

performance.now 是隐私评审最先查看的计时表面:没有任何权限提示拦住它,而它的精度和细小抖动描述的是下面那台机器。BotBrowser 可以在获得授权的测试中让部分计时值可复现,但它不能替代宿主机硬件,也不能保证所有检测器都会接受结果。

TL;DR

  • 这里的主信号是 performance.now() 的精度和抖动;hardwareConcurrency 和 deviceMemory 是通常与它一起读取的两个值。
  • VPN、隐私窗口和删除 Cookie 都不会改变本地硬件表面。
  • BotBrowser 的计时参数用于可复现验证,不等于匿名保证或检测器通过保证。

Contents

performance.now() 暴露了时钟的什么

计时 API 本来是为了让开发者测量自己的代码,但同一个时钟也让网站能够观察运行这些代码的机器。performance.now() 是每个字节携带信息最多的表面,因为读数的两个性质都决定在页面之外:时钟有多细,以及相邻读数之间抖动有多大。

这个调用返回自页面时间起点开始计算的高分辨率时间戳。浏览器会有意降低这个时钟的精度,MDN 的参考文档说明,更精细的分辨率只提供给跨源隔离的页面,一些注重隐私的浏览器模式还会进一步取整。降精度改变的是分辨率,不是形态。脚本重复执行同一段工作时,仍然能测出这段工作耗时多久,而耗时取决于 CPU 速度、缓存行为、调度,以及机器当时的繁忙程度。

这种降精度有其来历。高分辨率时钟曾被证明可用于 Spectre 类侧信道攻击,因此浏览器厂商降低了计时器精度、加入了抖动,并把更高的精度与跨源隔离绑定。这项缓解措施的设计目的是保护内存内容,而不是把硬件形态从画面中抹去。一个被反复读取的粗粒度计时器,仍然带有某台机器完成任务需要多长时间的信息,而这些读数之间的离散程度和读数本身一样说明问题。

还有两个值通常摆在时钟旁边,本文把它们当作背景而不是主题。hardwareConcurrency 报告浏览器可用的逻辑处理器数量,真实设备集中在 4、8、12 和 16 这类数值上。deviceMemory 返回大致的内存档位,单位为 GB,取整为 2 的幂并设有上限,基于 Chromium 的浏览器只在安全上下文中提供它。Worker 规划指南说明如何根据这个核心数确定池大小;这里只需要知道,把计时读数和它们放在一起比较会更有区分度。

示意图:performance.now 时钟、逻辑核心数和内存档位共同构成一个带有硬件形态的计时画像,并与已加载的配置文件对照

这些值都不需要权限提示,都不会产生可见的指示,也都不会因为删除 Cookie 而被清除。这就是它们出现在指纹研究中的原因,尽管每个数字单独看起来都无害。下面的章节说明这些读数如何组合,哪些常见的隐私措施对它们毫无影响,以及评审人员如何用 BotBrowser 配置并验证一致的报告时间。

为什么组合更有辨识度

单独来看,每个信号携带的信息都很少。许多设备的核心数相同,内存档位也只有几个可能的取值。组合则不同,因为网站可以一次性读取这三个值,再加上一小段计时样本。一台返回特定 performance.now() 差值分布、八个核心和 8 GB 内存档位的设备,所属的群体比只由其中任何一项描述的设备小得多。

这个组合还会与浏览器的其余部分对照。评审人员经常看到时间和硬件值与图形渲染器、屏幕尺寸、平台字符串和字体列表一起被读取,页面可以检查它们是否描述了同一台机器。一个声称是普通笔记本电脑、却返回高速工作站计时结果的配置文件,或者反过来,比一个单纯普通的配置文件更有辨识度。

设想评审一个测试配置文件,它描述的是一台有八个逻辑核心和 8 GB 内存档位的中端笔记本电脑。在你控制的页面上,核心数和内存档位的读取结果符合预期。随后的计时样本显示,循环完成的速度远快于这一档笔记本电脑,因为真实的宿主机是高端服务器。每个硬件值都与配置文件一致,计时却与它们不符。实际上,文档中说明的 0.80 到 0.99 缩放范围很窄,所以它可以缓和轻微的偏差,却不能把一档硬件变成另一档,只有把各个表面放在一起阅读的评审人员才会注意到这个差距。

稳定性与数值本身同样重要。报告的核心数在不同的页面加载之间发生变化,或者计时在一个标签页里表现一种样子、在下一个标签页里又是另一种样子,都比稳定但普通的值更有辨识度。这正是可重复的种子对评审有用的主要原因:它消除了一个变化来源,因此两次运行之间剩余的差异指向的是别的原因。

所以这个主题关乎一致性,而不是隐藏。认真的隐私评审,目标不是让每个数字都尽可能小,而是确保通过一个表面报告的硬件形态与通过其他表面报告的形态相符,并且这种相符在每次页面加载、每个 Worker 中以及长期内都成立。

三个问题有助于组织评审:

  • hardwareConcurrency 和 deviceMemory 是否描述了与已加载配置文件同一档的机器?
  • 同一页面上重复的计时样本看起来是否像同一档机器,并且在不同运行之间保持相近?
  • Navigation Timing 和 Resource Timing 条目是否与配置文件相符,而不是反映真实宿主机的连接?

VPN、隐私窗口、扩展和噪声留下了什么

VPN 改变网络路径和服务器看到的 IP 地址。它不会改变你的处理器运行一个循环有多快,不会改变浏览器报告多少个逻辑核心,也不会改变浏览器提供的内存档位。例如一台报告 hardwareConcurrency=8、deviceMemory=8 的机器仍可能与另一台报告 4 和 4 的机器共享同一个 VPN 出口。这三个值都在本地读取,所以位于同一个 VPN 出口之后的两台不同机器,仍然会报告不同的硬件形态。

隐私浏览窗口在关闭时会丢弃 Cookie、历史记录和网站数据。它们不会改变核心数、内存档位或底层硬件的速度,所以隐私窗口中的时间和硬件值,与同一台机器上普通窗口中的值一致。

重新安装浏览器、在同一台电脑上换用另一个浏览器,或者清除所有网站数据,处理器、核心数和内存都原封不动。不同的浏览器可能因为各自的取整规则和上限而报告不同的值,但同一台机器上的同一个浏览器是稳定的,这正是这些值能成为长期信号的原因。

覆盖硬件属性的扩展通常会注入一段脚本,在页面上重新定义某个属性。这可能留下明显的痕迹,例如属性描述符与浏览器自身的不同,或者新建的框架在扩展运行之前读到了真实的值。它还可能制造矛盾:页面报告四个核心,而 Worker 池明显并行运行了更多任务,这比未经修改的值更容易被注意到。

给计时值加入随机噪声也有类似的问题。带有人工抖动的时间戳序列与真实硬件的波动并不相似,它可能破坏你所访问页面上正当的性能监控,而且每次调用都变化的噪声本身就是一种可见的模式。稳定而合理的报告值通常比随机值更容易站得住脚。

一些浏览器自带保护,例如降低计时器精度或限制核心数。这些措施减少了页面能读到的信息,但它们适用于使用同一模式的所有人,所以报告的值变得常见而不是独特。它们也不会让这些值与任何特定的硬件档位相符,因此与所选配置文件的一致性仍然需要另行检查。

这并不意味着这些工具毫无意义。VPN 保护网络层,隐私窗口保护本地历史记录,扩展可以在许多跟踪器加载之前将其拦截。它们针对的是不同的表面。时间和硬件形态是它们从未被设计去覆盖的表面,所以评审必须单独对待并直接检查。

用 BotBrowser 配置文件配置报告的时间

从配置文件开始,因为配置文件定义了时间参数需要与之保持一致的硬件值。只带配置文件的启动,让你在加入任何时间参数之前先得到一个对照基线。然后逐个加入参数并记录变化。把每一步的控制台输出保存在启动命令旁边的纯文本文件中。

chromium-browser \
  --bot-profile="path/to/profile.enc" \
  --bot-time-scale=0.92 \
  --bot-time-seed=42

--bot-time-scale 压缩报告的高分辨率计时间隔。文档中说明的范围是 0.80 到 0.99,数值越接近 0.80,间隔被压缩得越多,越接近 0.99 则越少。文档把它的效果描述为模拟较低的系统负载并减少计时偏差信号。它是 ENT Tier2 参数。

--bot-time-seed 接受 1 到 4294967295 的整数,0 表示禁用。每个种子生成一个稳定的时间配置,在浏览器操作和导航计时条目中分布确定性的差异,因此相同的种子配合相同的配置文件,下次运行会得到相同的行为。它同样是 ENT Tier2 参数。

希望各实例彼此不同时,为每个实例使用不同的种子;希望测试可重复时,固定使用同一个种子。性能文档把各实例计时完全相同列为重复使用同一个种子的症状。缩放和种子针对计时的不同方面,文档说明它们可以一起使用。

--bot-performance-timing 是一个独立的参数,针对浏览器可见的计时条目,例如 Navigation Timing 和 Resource Timing 中的连接阶段。它接受 basic 和 advanced,需要 ENT Tier3,并且只有在当前配置文件包启用了 Performance Timing Protection 时才生效。它必须在第一个页面或 Worker 启动之前设置,并按浏览器上下文分别确定。省略它,或传入 false,即可保持该策略为禁用状态。

按固定顺序工作。先运行只带配置文件的基线并保存验证输出。加入时间缩放后对比。加入种子后再次对比。最后才加入 --bot-performance-timing,并且仅在你的等级和配置文件都支持时使用,因为它影响的表面与另外两个不同。一次改动所有参数,就无法分辨是哪个参数造成了哪种差异。规划测试之前,请先对照 CLI 参数参考确认你所在等级的覆盖范围,这样看起来不对的结果就不会只是因为你的等级不包含某个参数。

验证时间保持一致

只在你有权使用的页面和测试会话中进行验证。打开一个你控制的空白页面,用上面的配置文件和参数启动,并把读取到的内容与配置文件的描述对照。在读取任何值之前先写下你启动时使用的配置文件,这样对比就不是凭记忆进行的。下面的代码片段可以粘贴到该页面的开发者控制台中。

const { hardwareConcurrency, deviceMemory } = navigator;
const samples = [];
for (let run = 0; run < 5; run += 1) {
  const start = performance.now();
  for (let i = 0; i < 100000; i += 1) Math.sqrt(i);
  samples.push(performance.now() - start);
}
console.log({ hardwareConcurrency, deviceMemory, samples });

这段代码读取两个硬件值,并收集五个简短的计时样本。把输出当作一致性检查而不是基准测试:绝对数值取决于宿主机,你要看的是报告值与配置文件之间是否相符。

需要检查的内容:

  1. hardwareConcurrency 与配置文件描述的核心数一致。
  2. deviceMemory 与配置文件描述的内存档位一致。
  3. 五个样本彼此接近,并且用相同的配置文件、缩放和种子再次启动,会得到一致的模式。
  4. 只更改种子会改变这个模式,这证明种子已生效。
  5. 在专用 Worker 和 iframe 中读取同样的值,得到的硬件值与主页面相同。

计时样本永远不会完全相同,也不应该相同。真实硬件在不同运行之间会因调度和缓存状态而略有波动。完全平直的一组样本,或者剧烈摆动的一组样本,比带有细微自然波动的一组样本更值得怀疑。

无论脚本在哪里运行,硬件和计时值都应该读起来相同。网站创建专用 Worker 和框架就像读取主页面一样容易,所以它们之间的不一致很容易被发现。也要测试这些上下文,并把任何差异当作需要记录的发现,而不是需要解释掉的异常。

如果结果不符,一次只更改一项设置并重复运行,这正是性能文档建议的排查方法。常见原因是种子缺失或错误、配置文件不包含该功能,或者 ENT 等级不覆盖该参数。

公开的指纹测试页面可以提供第二种参考,但它们不会公布有保证的通过标准,某个页面上看起来干净的结果,并不是对其他任何网站的承诺。把每个页面当作一个数据点,并在得出结论之前对比多次运行。把确切的启动命令与结果放在一起,以便其他评审人员日后重复这次运行。

BotBrowser 的帮助与边界

BotBrowser 的文档记录了 --bot-time-scale 和 --bot-time-seed(ENT Tier2),用来压缩报告给页面内容的高分辨率计时间隔,并在配置文件定义的硬件值之外,为每个实例提供稳定、可由种子复现的时间配置,让你可以在不同的测试会话之间重复一致的计时。BotBrowser 不能改变宿主机执行 JavaScript 的真实速度,不能替代物理硬件,也不保证每个计时表面或每个第三方检测器都会接受这个结果;这些参数只改变报告给页面内容的值,并取决于 ENT 等级和配置文件的支持,其中 --bot-performance-timing 还需要 ENT Tier3 以及启用它的配置文件。

实际上,有用的成果是一个可复现的基线。你可以记录配置文件、缩放和种子,在另一天重新运行同样的检查,看看硬件形态或计时是否发生了漂移。这个说法比隐藏设备要窄,也正是这些参数的文档所支持的说法。

这些值描述的是设备,而不是人。时间和硬件形态只是众多输入之一,没有任何单个值能决定网站如何对待访客。本文不对任何跟踪器识别设备的准确程度做出声明;目的是帮助你检查浏览器报告的内容是否内部一致、记录是否如实。

一份评审记录最好包含:

  • 所用的配置文件和 BotBrowser 版本。
  • 确切的参数,包括缩放和种子。
  • 本次运行可用的 ENT 等级。
  • 读取到的硬件值和计时样本。
  • 检查的日期和所用的页面。

相关阅读涵盖相邻的表面。浏览器指纹概览解释信号如何组合,硬件并发与 Worker 规划更详细地讨论核心数,帧率控制介绍显示计时参数。

公开来源

实际结论

把计时和硬件值当作一致性证据,而不是把浏览器变得无法与另一台机器区分的承诺。先用配置文件做基线,每次只改变一个受支持的参数,记录完整命令和 ENT 等级,再在页面、Worker 和 iframe 中重复获得授权的检查。如果数值不一致,应记录差异并检查配置文件或宿主机,而不是加入无法解释的噪声。

#性能#Timing#浏览器指纹识别#隐私#Cpu#Hardware#Time-Seed

本文属于指南: 什么是浏览器指纹?原理、风险、信号与隐私边界

让 BotBrowser 从研究走向生产

先用这些指南理解模型,再进入跨平台验证、隔离上下文和面向规模化的浏览器部署。