无需麦克风的音频指纹识别

“音频指纹”听起来像是通过麦克风录下来的东西。其实不是。它是一个数字,来自你的机器处理一段合成声音的方式,这段声音从不播放、从不录制,也从不离开标签页。
它是如何产生的
脚本创建一个 OfflineAudioContext,它把音频渲染到内存中的缓冲区,而不是输出到扬声器。脚本将一个振荡器(通常是固定频率的三角波)经过动态压缩器连接到输出端,然后开始渲染。缓冲区就绪后,它读取其中一小段采样(通常是几百个值)并对其做哈希。结果是一个短字符串,例如 d4f50eb9。
整个操作只需几十毫秒,并且不需要任何权限,因为没有捕获任何内容。脚本完成后,OfflineAudioContext 即被关闭。
为什么不同机器的结果不同
压缩器和振荡器是在浏览器音频引擎内部用浮点运算实现的,确切的输出取决于引擎版本、操作系统的数学库、CPU 的浮点行为,在某些配置下还取决于音频硬件的采样率。差异极其微小,只是小数末几位上的几个比特,但哈希会把微小的差异放大成完全不同的字符串。与 Canvas 哈希一样,它在同一台机器上是稳定的,在不同机器之间则各不相同。
它的多样性低于 Canvas:许多使用相同浏览器版本和操作系统的机器会产生相同的音频哈希。它主要用作一种确认信号,以及用来检测那些对输出做随机化的浏览器。
浏览器的做法
Brave 对音频读回数据添加噪声,方式与处理 Canvas 相同。启用 resist-fingerprinting 的 Firefox 会禁用 Web Audio API 的部分功能,或返回恒定的值。Chromium 不会改动输出。对哈希做随机化的浏览器,每次刷新都会产生不同的值,而检测页面只要让你刷新并比较,就能让这一点一目了然。
准确地说隐私问题
没有录制任何声音,没有打开麦克风。缓冲区在计算期间存在于内存中,随后被丢弃。唯一可能离开标签页的是哈希,而且只有页面选择发送时才会发生。在本地计算哈希并展示给你的检测页面,读取的正是追踪者会读取的内容,然后什么也不做。
如何解读这个值
有两点值得检查。第一,哈希是否存在:“不可用”意味着该 API 被阻止,一些网站会把它本身视为一个信号。第二,它是否稳定:刷新后数值不应改变。哈希在多次加载之间发生变化,说明浏览器在注入噪声,这能防止跨站追踪,但同时也把这个浏览器标记成了会这样做的浏览器。


