002.chromium源码改写编译随机canvas指纹

本文介绍了如何利用JavaScript获取和生成Canvas指纹,以及如何通过添加随机元素来增加指纹的随机性,以防止网站过度追踪用户。通过修改浏览器源码,实现更难预测的用户标识符,提升用户隐私保护。
摘要由CSDN通过智能技术生成

通过源码编译随机canvas指纹

一、什么是canvas指纹

  • Canvas 指纹技术是一种在网站追踪用户行为和识别用户身份的方法。
  • 网站可以要求浏览器创建一个隐形的画布,并在这个画布上绘制图形,使用文字或其他视觉元素。
  • 绘制出的图像可能在像素级别上有微妙的差异。这些差异可以用来生成一个几乎独一无二的标识符——即所谓的“Canvas 指纹”。

二、获取浏览器的canvas指纹

  • 有攻才有防,先看看网站是如何通过js获取你的canvas指纹的。
  • 将下面的代码复制到F12控制台,就可以获取显示你的canvas指纹了。
async function sha256(message) {
    // 把字符串转换为Uint8Array
    const msgBuffer = new TextEncoder().encode(message);
    // 计算散列值
    const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
    // 转换为数组
    const hashArray = Array.from(new Uint8Array(hashBuffer));
    // 转换为16进制字符串
    const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
    return hashHex;
}

function getCanvasFingerprint() {
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    
    // 绘制一个简单的图形 —— 例如,文本。
    ctx.textBaseline = "top";
    ctx.font = "14px 'Arial'";
    ctx.textBaseline = "alphabetic";
    ctx.fillStyle = "#f60";
    ctx.fillRect(125, 1, 62, 20);
    
    // 设置一些canvas属性用来增加差异性
    ctx.fillStyle = "#069";
    ctx.fillText("Hello World!", 2, 15);
    ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
    ctx.fillText("Hello World!", 4, 17);

    // 绘制更多复杂的东西,比如变换或者路径
    ctx.strokeStyle = "rgba(0,0,0,0.2)";
    ctx.beginPath();
    ctx.lineTo(50, 100);
    ctx.stroke();
    
    // 尝试获取canvas图像数据
    var data = canvas.toDataURL(); // 获取图像的data URL
    
    // 创建一个hash值,比如使用SHA256或其他算法
    return data; // 假设sha256()是你的hash函数
}
sha256(getCanvasFingerprint()).then(hash => console.log(hash));

  • 输出:
62a60d12f6688e2f53425fa4e35d74d2afd61d30e9e1bfe58e47c7abc72bc2d7

注意:如果网站通过获取了你的canvas指纹,就算退出登录,网站基本也能确定,这个用户就是你了。信息就是这么泄漏的。

三、编译随机canvas指纹

  • 上篇文章写了如何编译chromium,假设你已经编译成功了。

  • 找到源码 \third_party\blink\renderer\modules\canvas\canvas2d\base_rendering_context_2d.cc

1.头部加上(随便加在一个#include后面)
#include <random>
2.替换掉原有代码
void BaseRenderingContext2D::fillText(const String& text, double x, double y) {
  DrawTextInternal(text, x, y, CanvasRenderingContext2DState::kFillPaintType);
}

void BaseRenderingContext2D::fillText(const String& text,
                                      double x,
                                      double y,
                                      double max_width) {
  DrawTextInternal(text, x, y, CanvasRenderingContext2DState::kFillPaintType,
                   &max_width);
}

替换为
int getRandomIntForFoo4Modern() {
    static std::mt19937 generator(static_cast<unsigned long>(time(NULL))); // 静态以确保只初始化一次
    std::uniform_int_distribution<int> distribution(0, 2);
    return distribution(generator);
}

void BaseRenderingContext2D::fillText(const String& text, double x, double y) {
  x = x + getRandomIntForFoo4Modern();
  y = y + getRandomIntForFoo4Modern();
  DrawTextInternal(text, x, y, CanvasRenderingContext2DState::kFillPaintType);
}

void BaseRenderingContext2D::fillText(const String& text,
                                      double x,
                                      double y,
                                      double max_width) {
  x = x + getRandomIntForFoo4Modern();
  y = y + getRandomIntForFoo4Modern();
  DrawTextInternal(text, x, y, CanvasRenderingContext2DState::kFillPaintType,
                   &max_width);
}

getRandomIntForFoo4Modern()函数是在0-2之间取一个随机数
系统每次调用fillText时加上随机偏移,偏移不宜太大,会导致图形混乱。

3.编译
ninja  -C  out/Default chrome
  • 找到out/Default chrome下新编译的执行文件chrome.exe执行
  • 再次看看canvas指纹,是不是每次访问都变成随机了。

四、还不够随机?

  • 将函数BaseRenderingContext2D::measureText替换成下面的代码
TextMetrics* BaseRenderingContext2D::measureText(const String& text) {
  // The style resolution required for fonts is not available in frame-less
  // documents.

  HTMLCanvasElement* canvas = HostAsHTMLCanvasElement();
  if (canvas) {
    if (!canvas->GetDocument().GetFrame()) {
      return MakeGarbageCollected<TextMetrics>();
    }

    canvas->GetDocument().UpdateStyleAndLayoutTreeForElement(
        canvas, DocumentUpdateReason::kCanvas);
  }

  const Font& font = AccessFont(canvas);

  const CanvasRenderingContext2DState& state = GetState();
  TextDirection direction = ToTextDirection(state.GetDirection(), canvas);
  
  //return MakeGarbageCollected<TextMetrics>(
  //   font, direction, state.GetTextBaseline(), state.GetTextAlign(), text);
  
  int tmp = getRandomIntForFoo4Modern();
  String tmp_text;
  if (tmp == 0) {
    tmp_text = text + " ";
  }else{
	tmp_text = text;
  }
  
  return MakeGarbageCollected<TextMetrics>(
      font, direction, state.GetTextBaseline(), state.GetTextAlign(), tmp_text);
}

上述代码的意思是每次渲染文字时,随机给文字追加一个空字符。
这样每次测量canvas尺寸肯定就是随机啦。

五、在线指纹验证网站:

  • https://browserleaks.com/canvas
  • https://abrahamjuliot.github.io/creepjs/

看看有没有人关注,有人的话再继续写吧

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王辉辉的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值