浏览器指纹开发教程

Canvas 指纹怎么生成

详解 Canvas 指纹的生成机制,包括绘制原理、哈希提取方法、不同设备产生差异的根本原因,以及如何在指纹浏览器中修改 Canvas 指纹。


Canvas 指纹怎么生成

Canvas 指纹是浏览器指纹中最重要、最稳定的参数之一。它利用 HTML5 Canvas 的图形渲染差异,在不同设备上生成几乎唯一的标识值。

生成原理

Canvas 指纹的核心思想是:同一图形指令在不同硬件和软件环境下的渲染结果存在细微差异

这些差异来源于:

  • 显卡型号与驱动:NVIDIA、AMD、Intel 核显的渲染算法不同
  • 操作系统:Windows、macOS、Linux 的字体渲染和抗锯齿策略不同
  • 浏览器内核:Chromium、Firefox、Safari 的图形管线实现不同
  • 浏览器版本:同一浏览器不同版本的渲染引擎可能有微调

标准生成流程

第一步:创建离屏画布

const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 50;
const ctx = canvas.getContext('2d');

第二步:绘制复合图形

关键是在画布上混合多种元素(文本、几何图形、渐变、阴影),最大化渲染差异:

function drawFingerprintCanvas(ctx, width, height) {
  // 背景渐变
  const gradient = ctx.createLinearGradient(0, 0, width, height);
  gradient.addColorStop(0, '#f60');
  gradient.addColorStop(1, '#ff6');
  ctx.fillStyle = gradient;
  ctx.fillRect(0, 0, width, height);

  // 阴影设置
  ctx.shadowColor = 'rgba(0,0,0,0.3)';
  ctx.shadowBlur = 5;
  ctx.shadowOffsetX = 2;
  ctx.shadowOffsetY = 2;

  // 主文本
  ctx.textBaseline = 'alphabetic';
  ctx.font = 'bold 18px Arial, sans-serif';
  ctx.fillStyle = '#069';
  ctx.fillText('EasyBR Canvas FP', 10, 25);

  // 叠加文本(制造抗锯齿差异)
  ctx.font = 'italic 14px Georgia, serif';
  ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
  ctx.fillText('Browser Fingerprint', 12, 40);

  // 几何图形
  ctx.beginPath();
  ctx.arc(170, 20, 12, 0, Math.PI * 2);
  ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
  ctx.fill();
  ctx.strokeStyle = '#00f';
  ctx.lineWidth = 2;
  ctx.stroke();

  // 贝塞尔曲线
  ctx.beginPath();
  ctx.moveTo(10, 45);
  ctx.bezierCurveTo(50, 35, 100, 55, 140, 40);
  ctx.strokeStyle = 'rgba(0, 255, 255, 0.6)';
  ctx.lineWidth = 1.5;
  ctx.stroke();
}

第三步:提取像素数据并哈希

async function getCanvasFingerprint() {
  const canvas = document.createElement('canvas');
  canvas.width = 200;
  canvas.height = 50;
  const ctx = canvas.getContext('2d');

  drawFingerprintCanvas(ctx, 200, 50);

  // 方法 1:toDataURL(Base64 编码的 PNG)
  const dataUrl = canvas.toDataURL('image/png');

  // 方法 2:getImageData(原始像素数组)
  const imageData = ctx.getImageData(0, 0, 200, 50);
  const pixels = imageData.data; // Uint8ClampedArray

  // 哈希计算
  const hash = await hashPixels(pixels);
  return { hash, dataUrlLength: dataUrl.length };
}

async function hashPixels(pixels) {
  const buffer = pixels.buffer;
  const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
  return Array.from(new Uint8Array(hashBuffer))
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');
}

为什么会产生差异

1. 字体渲染差异

不同操作系统对同一字体的字形、字距、抗锯齿处理不同。例如 Arial 在 Windows ClearType、macOS 子像素渲染、Linux FreeType 下的显示效果有明显差异。

2. 抗锯齿算法

各浏览器使用不同的抗锯齿策略:

  • Chromium:基于 Skia 图形库
  • Firefox:基于 Gecko 自己的渲染管线
  • Safari:基于 WebKit 的 CoreGraphics

3. 色彩空间处理

sRGB 与其他色彩空间的转换在不同实现中有舍入差异。

4. GPU 加速差异

部分浏览器对 Canvas 操作使用 GPU 加速,部分使用 CPU 软渲染,结果可能不同。

在 EasyBR 中修改 Canvas 指纹

EasyBR 指纹浏览器通过以下方式修改 Canvas 指纹:

  • 噪声注入:在渲染结果的像素数据中注入微小噪声,使哈希值改变但人眼不可察觉
  • CPU 模拟:强制使用 CPU 软渲染,绕过 GPU 差异
  • 一致性保持:同一环境内的多次 Canvas 指纹采集结果保持一致
注意:EasyBR 的 Canvas 指纹修改是"噪声型"而非"替换型",
即不会替换成另一台设备的指纹,而是在原有基础上添加可控噪声。
这样可以避免与真实设备指纹完全重合导致的异常标记。

风险边界

  • Canvas 修改可被检测:部分高级反作弊系统会检测 Canvas 指纹的”噪声特征”,过度修改可能反而被标记
  • toDataURL 和 getImageData 结果需一致:如果两者返回的指纹不同,会被视为异常
  • 性能开销:噪声注入会增加少量渲染开销,对普通页面影响很小
  • 不保证 100% 通过检测:Canvas 指纹只是防关联的一个环节,需配合 IP、Cookie、行为等多个维度

测试你的 Canvas 指纹

// 快速测试脚本,可在浏览器控制台运行
(async () => {
  const c = document.createElement('canvas');
  c.width = 200; c.height = 50;
  const x = c.getContext('2d');
  x.textBaseline = 'top';
  x.font = '14px Arial';
  x.fillText('Test Canvas FP', 2, 2);
  const d = c.toDataURL();
  const h = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(d));
  console.log('Canvas FP:', Array.from(new Uint8Array(h)).map(b => b.toString(16).padStart(2,'0')).join('').slice(0,16));
})();

FAQ

Q: Canvas 指纹在不同浏览器上是否相同?
A: 通常不同。即使同一台电脑,Chrome 和 Firefox 的 Canvas 渲染结果也可能不同,因为底层图形引擎不同。

Q: 禁用 Canvas 能防止指纹采集吗?
A: 能防止 Canvas 指纹,但会严重破坏现代网站功能(如图表、游戏、图片处理)。大部分网站不会完全禁用 Canvas。

Q: Canvas 指纹修改后,图片显示会变模糊吗?
A: 优质指纹浏览器的噪声注入是人眼不可察觉的(像素级微小变化),不会影响正常浏览体验。

Q: 为什么有些网站能检测 Canvas 被修改?
A: 网站可以通过以下方式检测:1) 比较 toDataURL 和 getImageData 的一致性;2) 检测渲染时间异常;3) 分析像素统计特征。

Q: Canvas 指纹和 WebGL 指纹哪个更重要?
A: 两者同等重要且互补。Canvas 主要反映字体和 2D 渲染差异,WebGL 主要反映 GPU 差异。建议同时保护两者。


延伸阅读


文章作者: easybr官方
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 easybr官方 !
Next Step

先试 EasyBR,再决定是否扩团队或做更深的定制项目

标准版适合先验证多账号环境、代理和数据迁移;如果你需要更深的业务能力,我们也支持浏览器外包、Chromium 定制、贴牌浏览器与 Android 指纹浏览器开发。

下载免费版 联系团队 查看技术服务
 上一篇
浏览器指纹包含哪些参数 浏览器指纹包含哪些参数
系统梳理浏览器指纹的全部组成参数,分为基础环境、渲染特征、硬件信息、网络特征、行为特征五大类,并说明每类参数的采集方式和防关联意义。
下一篇 
WebGL 指纹检测原理 WebGL 指纹检测原理
详解 WebGL 指纹的检测原理,包括 GPU 信息提取、渲染管线差异、参数枚举方法,以及指纹浏览器如何修改 WebGL 指纹以规避关联检测。
  目录