头像

识别cavas指纹是否被篡改

2026-02-10

Written by: Jack-S-H

这里提供两种识别方法

Security

Js

工作量证明方法——要求用户绘制画布并验证某些已知像素的数值.

生成一个特定颜色的画布,并验证特定像素的数值是否符合预期的。下面的代码片段展示了一个简单的示例,我们将画布填充为 rgba(0, 127, 255, 1)。然后,我们对每个像素进行迭代,验证 r、g、b、a 的分量是否具有期望值(因此代码中使用%4)。

var canvas = document.createElement("canvas");
canvas.height = size;
canvas.width = size;
var context = canvas.getContext("2d");
context.fillStyle = "rgba(0, 127, 255, 1)";
var pixelValues = [0, 127, 255, 255];
// 应用颜色
context.fillRect(0, 0, canvas.width, canvas.height);
var pixels = context.getImageData(0, 0, canvas.width, canvas.height).data;
for (var i = 0; i < pixels.length; i += 1) {
    if (pixels[i] !== pixelValues[i % 4]) {
        // 执行测试
        // 如果不匹配,则代表指纹被篡改
        console.log('Canvas has been overridden!')
    }
}

函数一致性检查方法

通过查看函数的原型或错误堆栈痕迹等副作用检测函数是否被覆盖

检测由js代理调用的反指纹脚本
let isOverridden = true;
try {
    Object.setPrototypeOf(HTMLCanvasElement.prototype.toDataURL, HTMLCanvasElement.prototype.toDataURL)
} catch (e) {
    if (e.message.indexOf('Cyclic') > -1) {
        isOverridden = false;
    }
}
正常情况会报错

通过监控错误堆栈,来检测特定扩展
var canvas = document.createElement('canvas');
var context = canvas.getContext("2d");
try {
    context.getImageData(canvas);   
} catch (e) {
    hasAntiCanvasExtension = e.stack.indexOf('chrome-extension') > -1;
    hasCanvasBlocker = e.stack.indexOf('nomnklagbgmgghhjidfhnoelnjfndfpd') > -1;
}