浏览器指纹(Browser Fingerprinting)是一种在不使用Cookie等技术的情况下,通过收集设备硬件和软件的独特特征来识别用户的技术。
它的核心原理在于,即便是细微的硬件或软件差异,也会导致浏览器在执行特定任务(如图形、音频渲染)时产生完全不同的输出结果,从而生成一个高熵值的唯一标识符。
以下是实现这三种主流指纹技术的详细JavaScript方法。
1. Canvas指纹
Canvas指纹是目前最成熟、识别率最高的技术。它利用不同设备在GPU、显卡驱动、操作系统及浏览器渲染引擎上的差异来提取指纹。
实现原理:脚本会在后台创建隐藏的画布,通过组合绘制文字、几何图形、阴影和渐变等指令,最大程度地触发系统底层的渲染差异。
核心代码:
function getCanvasFingerprint() {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 200;
canvas.height = 50;
// 1. 设置文字样式,触发不同平台的字体渲染差异
ctx.textBaseline = "top";
ctx.font = "14px 'Arial'";
ctx.fillStyle = "#f60";
ctx.fillRect(125, 1, 62, 20);
// 2. 绘制带特殊符号和透明度的文字,触发GPU的颜色混合与抗锯齿算法
ctx.fillStyle = "#069";
ctx.fillText("Hello, world! ", 2, 15); // 特殊符号(Emoji)检测字体库
ctx.fillStyle = "rgba(102, 204, 0, 0.7)"; // 透明度触发抗锯齿差异
ctx.fillText("Hello, world! ", 4, 17);
// 3. 导出为Base64字符串,不同设备/浏览器生成的字符串会有差异
const base64 = canvas.toDataURL().replace("data:image/png;base64,", "");
// 4. 将字符串哈希化,生成最终的指纹
// 注意:这里仅为示例,生产环境中建议使用更健壮的哈希算法,如SHA-256
let hash = 0;
for (let i = 0; i < base64.length; i++) {
const char = base64.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash |= 0; // Convert to 32bit integer
}
return hash.toString();
} 工作原理:虽然肉眼看到的图形可能完全相同,但将Base64字符串哈希后,你会发现不同设备生成的哈希值有微小差异,这就是显卡和渲染器留下的独特“签名”。为了获得更可靠的指纹,通常会使用SHA-256等加密哈希函数来处理导出的图片数据。
2. AudioContext指纹
AudioContext指纹利用的是不同设备在音频信号处理上的细微差别,主要源于硬件(DSP)、软件(音频栈)和浏览器实现的不同。
实现原理:它不需要麦克风权限,而是生成一个数学上的声音信号(正弦波、三角波等),通过压缩器(DynamicsCompressor)等节点处理后,分析输出的音频数据流。
核心代码:
function getAudioFingerprint() {
return new Promise((resolve, reject) => {
// 1. 创建离线音频上下文
const context = new (window.OfflineAudioContext || window.webkitOfflineAudioContext)(1, 44100, 44100);
// 2. 创建振荡器并生成三角波信号
const oscillator = context.createOscillator();
oscillator.type = 'triangle';
oscillator.frequency.setValueAtTime(10000, context.currentTime);
// 3. 创建压缩器,增强处理过程中的软硬件特性
const compressor = context.createDynamicsCompressor();
// 4. 连接节点:振荡器 -> 压缩器 -> 输出扬声器
oscillator.connect(compressor);
compressor.connect(context.destination);
// 5. 启动并开始渲染
oscillator.start(0);
context.oncomplete = (event) => {
// 6. 获取渲染后的音频数据
const renderedBuffer = event.renderedBuffer;
const outputData = renderedBuffer.getChannelData(0);
// 7. 对音频数据采样求和,生成最终的指纹
let hash = 0;
for (let i = 0; i < outputData.length; i++) {
// 简单的哈希算法,生产环境应使用更复杂的方法
hash += Math.abs(outputData[i]);
}
resolve(hash.toString());
};
context.startRendering();
});
} 工作原理:不同设备处理“三角波”并通过“压缩器”时,由于硬件和软件的差异,会引入极其微小的、独特的处理痕迹。通过计算生成的PCM音频数据流的摘要,就能获得一个高度唯一的音频指纹。
3. WebGL渲染特征
WebGL指纹通过暴露底层的显卡和驱动信息来识别设备,它提供了比Canvas指纹更直接的硬件标识符。
实现原理:通过WebGL API,可以查询到GPU的详细硬件参数,并与Canvas结合,像Canvas指纹那样通过渲染特定3D场景来获取图像哈希值。
核心代码:
function getWebGLFingerprint() {
// 1. 创建Canvas并获取WebGL上下文
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) return null;
// 2. 获取调试渲染信息(GPU型号等核心特征)
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
const vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL); // 显卡供应商
const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL); // 显卡型号
// 3. 收集其他稳定参数
const parameters = {
vendor: vendor,
renderer: renderer,
maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE), // 最大纹理尺寸
maxViewportDims: gl.getParameter(gl.MAX_VIEWPORT_DIMS), // 最大视口尺寸
};
// 4. 将收集到的信息生成指纹
const fingerprintString = JSON.stringify(parameters);
// 5. 转换为哈希值(此处为简单示例)
let hash = 0;
for (let i = 0; i < fingerprintString.length; i++) {
const char = fingerprintString.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash |= 0;
}
return hash.toString();
} 工作原理:代码会返回不同操作系统、GPU和浏览器组合下的渲染器字符串(如下所示),这些信息构成了设备在WebGL下的“身份证”。
Windows (NVIDIA): ANGLE (NVIDIA, NVIDIA GeForce RTX 2060 SUPER Direct3D11 vs_5_0 ps_5_0, D3D11)
macOS (Apple M1): ANGLE (Apple, ANGLE Metal Renderer: Apple M1 Pro, Unspecified Version)
总结与最佳实践
为了生成一个高唯一性且稳定的浏览器指纹,通常需要组合使用以上多种技术。
最佳实践:
组合使用:综合Canvas、AudioContext、WebGL,并结合其他信息(如屏幕分辨率、字体列表、用户代理等),可生成一个熵值极高的唯一指纹。
稳健的哈希算法:为降低碰撞风险,建议使用SHA-256或MurmurHash3等哈希算法,而非代码示例中的简单算法。
用户授权:某些浏览器(如Chrome)对AudioContext有自动播放策略限制,可能需要用户手势(如点击)才能启动。
隐私合规:在全球范围内(如GDPR),对用户进行指纹识别通常需要明确的知情同意。
网友回复
ai能写出比黑客还厉害的零日漏洞等攻击工具攻击任意软件系统工程?
js如何获取浏览器的音频上下文指纹、Canvas指纹、WebGL渲染特征?
为啥ai开始抛弃markdown文本,重新偏好html文本了?
网站有没有办法鉴别访问请求是由ai操控chrome-devtools-mcp发出的?
有没有python自动操作浏览器让网站无法鉴别是机器行为?
为啥最新由Meta / 斯坦福 / 哈佛出的ProgramBench基准GPT-5.4、Claude Opus 4.7、Gemini 3.1 Pro 等全部 0% 通过率?
有没有免费的api查询域名是否完成icp工信部备案?
codex用HyperFrames与 Remotion自动做视频那个更好?
claude code中Skill MCP CLI SubAgent Hooks Plugin区别?
浏览器webrtc点对点通讯如何才能走系统代理?


