Cross-Browser-Tracking-Summary-Part-3
字数 1682 2025-08-27 12:33:54

WebGL指纹识别与语言检测技术详解

一、WebGL指纹识别技术

1. 核心原理

WebGL指纹识别利用不同设备GPU渲染结果的微小差异作为设备标识。关键技术点包括:

  • 渲染差异:不同GPU硬件、驱动版本对同一WebGL指令会产生略微不同的渲染结果
  • 数据采集:通过readPixels方法获取渲染后的像素数据
  • 哈希处理:将像素数据转换为唯一哈希值作为指纹

2. 关键代码实现

this.getData = function(gl, id) {
    if (!this.finalized) {
        throw "Still generating ID's";
        return -1;
    }
    var WebGL = true;
    var pixels = new Uint8Array(256 * 256 * 4);
    gl.readPixels(0, 0, 256, 256, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
    
    var ven, ren;
    var debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
    if (debugInfo) {
        ven = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
        ren = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
    } else {
        console.log("debugInfo is not accessable");
        ven = 'No debug Info';
        ren = 'No debug Info';
    }
    
    var hash = pixels.hashCode();
    this.toServer(WebGL, ven, ren, hash, id, pixels);
    
    if (sumRGB(pixels) > 1.0) {
        return hashRGB(pixels);
    } else {
        return 0;
    }
};

3. 技术要点解析

  1. readPixels参数详解

    gl.readPixels(x, y, width, height, format, type, pixels);
    
    • 前4个参数:(0, 0, 256, 256)表示从画布左上角开始读取256x256像素区域
    • 第5参数:gl.RGBA表示读取RGBA四通道数据
    • 第6-7参数:gl.UNSIGNED_BYTEpixels表示将数据读取到无符号字节数组中
  2. 像素数据结构

    • 单个像素返回格式:[Red, Green, Blue, Alpha],例如[0, 0, 0, 255]
    • 256x256图像数据存储在256*256*4=262144长度的Uint8Array中
  3. GPU信息获取

    var debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
    if (debugInfo) {
        ven = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
        ren = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
    }
    
    • 获取GPU厂商和渲染器信息作为辅助识别数据

4. 实际测试结果

  • 不同设备、相同浏览器:渲染hash值不同
  • 相同设备、不同浏览器:渲染hash值大部分一致
  • 结论:GPU渲染差异可作为跨浏览器设备指纹特征

二、语言/文字系统检测技术

1. 核心原理

通过检测浏览器对不同文字系统的渲染支持情况,识别用户环境特征:

  • 利用DOM元素测量不同字符的渲染尺寸
  • 比较实际渲染尺寸与预期尺寸的差异
  • 判断浏览器对特定文字系统的支持情况

2. 代码实现(CoffeeScript)

class LanguageDetector
    constructor: ->
        @names = safeParseJSON '[ "Latin", "Chinese", ... ]'
        @codes = safeParseJSON "[[76,97,116,105,110], [27721,23383], ... ]"
        @fontSize = 9
        @fontFace = "Verdana"
        @extraHeigth = 15
        @results = []

3. 实现步骤详解

  1. 基础定义

    • 定义36种语言/文字系统名称(如Latin、Chinese等)
    • 定义各文字系统的Unicode测试字符
    • 设置统一的字体和大小(Verdana, 9pt)
  2. 长宽识别

    @div = document.createElement "div"
    @test_div.appendChild @div
    @div.innerHTML = "<font face = '#{@fontFace}' size = " + @fontSize + ">&#" + c + "</font>"
    @height.push document.getElementById(round).clientHeight
    @width.push document.getElementById(round).clientWidth
    
    • 为每个测试字符创建div元素
    • 测量并记录每个字符的渲染高度和宽度
  3. 长宽校验

    @sh = @heights.pop()[0]  # 获取无法渲染字符的基准尺寸
    for height in @heights
        @passed = 0
        for h in height
            if h != @sh
                @support.push true
                @passed = 1
                break
        if @passed == 0
            @support.push false
    
    • 使用无法渲染的字符作为基准(@codes数组第37项)
    • 比较各字符尺寸与基准尺寸的差异
    • 尺寸不同⇒支持该文字系统;相同⇒不支持
  4. 统计结果

    @res = []
    for s,i in @support
        if s == true
            @res.push @names[i]
    
    • 收集所有被支持的文字系统名称

4. 技术要点解析

  1. 基准字符选择

    • 使用无法渲染的字符(如U+1B83)作为基准
    • 避免直接使用方块字符,因为不同浏览器可能渲染为不同形状
  2. 测量原理

    • 支持的字符:实际渲染尺寸 ≠ 基准尺寸
    • 不支持的字符:浏览器可能显示为方块或问号,尺寸与基准相同
  3. 多字符测试

    • 每个文字系统测试多个字符,提高准确性
    • 只要有一个字符被正确渲染,即判定支持该文字系统

5. 实际测试结果

不同浏览器支持的文字系统存在差异:

  • Chrome:支持30种
  • Safari:支持36种
  • 差异原因:不同浏览器对罕见文字系统的渲染支持不同

三、应用与防御

1. 实际应用场景

  1. 设备指纹

    • WebGL指纹 + 语言支持特征 → 高精度设备识别
    • 跨浏览器追踪同一设备
  2. 用户画像

    • 语言支持特征可推测用户区域/语言偏好
    • 结合其他指纹增强用户画像精度
  3. 反欺诈

    • 检测虚拟机/异常环境
    • 识别自动化工具

2. 防御措施

  1. WebGL指纹防御

    • 禁用WebGL
    • 使用Canvas Blocker等插件干扰渲染结果
    • 浏览器隐私模式可能限制信息获取
  2. 语言检测防御

    • 统一所有字符的渲染尺寸
    • 干扰DOM元素尺寸测量
    • 禁用罕见文字系统的字体
  3. 综合防御

    • 使用Tor浏览器等隐私保护浏览器
    • 定期清理浏览器指纹特征
    • 使用虚拟机/容器隔离不同身份

四、总结

本文详细解析了两种重要的浏览器指纹技术:

  1. WebGL指纹

    • 利用GPU渲染差异生成设备唯一标识
    • 高稳定性,跨浏览器有效
    • 实现涉及WebGL渲染和像素数据采集
  2. 语言/文字系统检测

    • 基于字体渲染支持情况的被动检测
    • 可识别浏览器/系统区域设置
    • 实现依赖DOM测量和Unicode知识

这两种技术结合其他指纹方法,可构建高精度的用户追踪系统。理解其原理有助于开发隐私保护策略,平衡功能与隐私的需求。

WebGL指纹识别与语言检测技术详解 一、WebGL指纹识别技术 1. 核心原理 WebGL指纹识别利用不同设备GPU渲染结果的微小差异作为设备标识。关键技术点包括: 渲染差异 :不同GPU硬件、驱动版本对同一WebGL指令会产生略微不同的渲染结果 数据采集 :通过 readPixels 方法获取渲染后的像素数据 哈希处理 :将像素数据转换为唯一哈希值作为指纹 2. 关键代码实现 3. 技术要点解析 readPixels参数详解 : 前4个参数: (0, 0, 256, 256) 表示从画布左上角开始读取256x256像素区域 第5参数: gl.RGBA 表示读取RGBA四通道数据 第6-7参数: gl.UNSIGNED_BYTE 和 pixels 表示将数据读取到无符号字节数组中 像素数据结构 : 单个像素返回格式: [Red, Green, Blue, Alpha] ,例如 [0, 0, 0, 255] 256x256图像数据存储在 256*256*4=262144 长度的Uint8Array中 GPU信息获取 : 获取GPU厂商和渲染器信息作为辅助识别数据 4. 实际测试结果 不同设备、相同浏览器:渲染hash值不同 相同设备、不同浏览器:渲染hash值大部分一致 结论:GPU渲染差异可作为跨浏览器设备指纹特征 二、语言/文字系统检测技术 1. 核心原理 通过检测浏览器对不同文字系统的渲染支持情况,识别用户环境特征: 利用DOM元素测量不同字符的渲染尺寸 比较实际渲染尺寸与预期尺寸的差异 判断浏览器对特定文字系统的支持情况 2. 代码实现(CoffeeScript) 3. 实现步骤详解 基础定义 : 定义36种语言/文字系统名称(如Latin、Chinese等) 定义各文字系统的Unicode测试字符 设置统一的字体和大小(Verdana, 9pt) 长宽识别 : 为每个测试字符创建div元素 测量并记录每个字符的渲染高度和宽度 长宽校验 : 使用无法渲染的字符作为基准(@codes数组第37项) 比较各字符尺寸与基准尺寸的差异 尺寸不同⇒支持该文字系统;相同⇒不支持 统计结果 : 收集所有被支持的文字系统名称 4. 技术要点解析 基准字符选择 : 使用无法渲染的字符(如U+1B83)作为基准 避免直接使用方块字符,因为不同浏览器可能渲染为不同形状 测量原理 : 支持的字符:实际渲染尺寸 ≠ 基准尺寸 不支持的字符:浏览器可能显示为方块或问号,尺寸与基准相同 多字符测试 : 每个文字系统测试多个字符,提高准确性 只要有一个字符被正确渲染,即判定支持该文字系统 5. 实际测试结果 不同浏览器支持的文字系统存在差异: Chrome :支持30种 Safari :支持36种 差异原因:不同浏览器对罕见文字系统的渲染支持不同 三、应用与防御 1. 实际应用场景 设备指纹 : WebGL指纹 + 语言支持特征 → 高精度设备识别 跨浏览器追踪同一设备 用户画像 : 语言支持特征可推测用户区域/语言偏好 结合其他指纹增强用户画像精度 反欺诈 : 检测虚拟机/异常环境 识别自动化工具 2. 防御措施 WebGL指纹防御 : 禁用WebGL 使用Canvas Blocker等插件干扰渲染结果 浏览器隐私模式可能限制信息获取 语言检测防御 : 统一所有字符的渲染尺寸 干扰DOM元素尺寸测量 禁用罕见文字系统的字体 综合防御 : 使用Tor浏览器等隐私保护浏览器 定期清理浏览器指纹特征 使用虚拟机/容器隔离不同身份 四、总结 本文详细解析了两种重要的浏览器指纹技术: WebGL指纹 : 利用GPU渲染差异生成设备唯一标识 高稳定性,跨浏览器有效 实现涉及WebGL渲染和像素数据采集 语言/文字系统检测 : 基于字体渲染支持情况的被动检测 可识别浏览器/系统区域设置 实现依赖DOM测量和Unicode知识 这两种技术结合其他指纹方法,可构建高精度的用户追踪系统。理解其原理有助于开发隐私保护策略,平衡功能与隐私的需求。