浏览器指纹的生成

文章介绍了浏览器指纹的生成原理,包括普通指纹和高级指纹。重点讲述了Canvas指纹、WebGL指纹和Audio音频指纹的生成过程及其实现代码,强调这些高级指纹在提高客户端唯一性识别准确性上的作用。

作者:中国移动云能力中心  ——谢雷

概要:我们在日常网络冲浪的时候,肯定都有过这样的经历: 在某东/某宝上浏览过电动牙刷后,再访问其他网站时总会在边角看到大大小小类似的商品广告。 文章主要分享如何生成浏览器指纹,用以精准定位用户。

“浏览器指纹”是一种通过浏览器对网站可见的配置和设置信息来跟踪Web浏览器的方法,浏览器指纹就像我们人手上的指纹一样,具有个体辨识度,只不过现阶段浏览器指纹辨别的是浏览器。

查看浏览器指纹信息:https://amiunique.org/fp

人手上的指纹之所以具有唯一性,是因为每个指纹具有独特的纹路、这个纹路由凹凸的皮肤所形成。每个人指纹纹路的差异造就了其独一无二的特征。

那么浏览器指纹也是同理,获取浏览器具有辨识度的信息,进行一些计算得出一个值,那么这个值就是浏览器指纹。辨识度的信息可以是UA、时区、地理位置或者是你使用的语言等等,你所选取的信息决定了浏览器指纹的准确性。

浏览器指纹也可以进行简单的分为普通指纹和高级指纹,普通指纹可以理解为容易被发现并且容易修改的部分,例如http的header

{
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", 
    "Accept-Encoding": "gzip, deflate, br", 
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", 
    "Host": "httpbin.org", 
    "Sec-Fetch-Mode": "navigate", 
    "Sec-Fetch-Site": "none", 
    "Sec-Fetch-User": "?1", 
    "Upgrade-Insecure-Requests": "1", 
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"
  }
}

比如硬件类型(Apple)、操作系统(Mac OS)、用户代理(User agent)、系统字体、语言、屏幕分辨率、浏览器插件 (Flash, Silverlight, Java, etc)、浏览器扩展、浏览器设置 (Do-Not-Track, etc)、时区差(Browser GMT Offset)等众多信息。

普通指纹就像人的外貌、身高、体重、性别,很难从肉眼的角度去区分浏览器,那么高级指纹对于浏览器来说,就像DNA一般精准(不要害怕,也是有极限的)这里会着重介绍目前广泛使用的三大高级指纹:canvas指纹/WebGL指纹/Audio音频指纹。

1)canvas指纹
Canvas(画布)是HTML5中一种动态绘图的标签,可以使用其生成甚至处理高级图片,2014年9月,ProPublica报道:新型的Canvas指纹追踪正在被用到“上到白宫,下到YouPorn”等众多网站,其高级指纹的地位,可见一斑。
canvas指纹的生成过程大致如下:

利用画布绘制指定图案
使用canvas.toDataURL()的方法获得图片内容的base64编码
将其CRC校验码作为唯一性标识(对于PNG格式的图片,以块(chunk)划分,最后一块是32位CRC校验)
在众多博客中对canvas原理的介绍基本上是一句带过:
相同的HTML5 Canvas元素绘制操作,在不同操作系统、不同浏览器上,产生的图片内容不完全相同。在图片格式上,不同浏览器使用了不同的图形处理引擎、不同的图片导出选项、不同的默认压缩级别等。在像素级别来看,操作系统各自使用了不同的设置和算法来进行抗锯齿和子像素渲染操作。即使相同的绘图操作,产生的图片数据的CRC检验也不相同。

 代码实现:

function getUid() {
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");
  ctx.fillStyle = "#FC9630";
  ctx.fillRect(0, 0, 8, 8);

  const base64 = canvas.toDataURL().replace("data:image/png;base64,", "");
  return bin2hex(window.atob(base64).slice(-16, -12));
}

function bin2hex(s = "") {
  const _s = s + "";
  const f = _s.length,
    a = [];

  for (let i = 0; i < f; i++) {
    a[i] = _s
      .charCodeAt(i)
      .toString(16)
      .replace(/^([\da-f])$/, "0$1");
  }

  return a.join("");
}

const uid = getUid();
console.log(uid);

canvas指纹信息

2)WebGL指纹

有了canvas指纹的理解基础,WebGL就更好理解一些了,基本上是同样的原理,只不过这里会将画好的3D图像内容和WebGL的某些属性值绑定在一起(比如渲染图片用到的显卡提供商以及显卡型号,压缩等级等等)拼接成一个很长的字符串,哈希过后取得一个缩减过信息量却又保留了信息差的的字符串作为WebGL指纹

在运行WebGL程序时,我们可以拿到用户机器的一些硬件信息,尤其是显卡的信息。

代码实现:

var canvas = document.createElement('canvas');
var gl = canvas.getContext('webgl');

var debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
//获得产品名和供应商名
var vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
var renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
...

webgl指纹信息

mozilla webgl api

3)音频指纹

音频上下文借助OS和音频卡中的音频堆栈,为音频信号产生到信号滤波,提供处理功能。具体来说,现有的指纹识别工作使用振荡器节点生成三角波,然后将波馈入产生压缩效果的信号处理模块,该节点可以抑制较大的声音以及放大微小的声音。 然后,经处理的音频信号通过分析节点转换为频域。
  这种波形在同一台机不同浏览器是不一样的.但是对于跨浏览器,其峰值和它们对应的频率相对稳定.通过映射关系可以将这个作为跨浏览器的特征.其中作为特征的有采样率,最大通道数,输入数,输出数,通道数,通道计数模式和通道解释。

HTML5提供给JavaScript编程用的Audio API则让开发者有能力在代码中直接操作原始的音频流数据,对其进行任意生成、加工、再造,诸如提高音色,改变音调,音频分割等多种操作,甚至可称为网页版的Adobe Audition。
其大致原理如下,方法有二:

生成特定的音频信息流,对其进行一系列操作后,计算SHA值作为指纹,音频输出到音频设备之前进行清除,用户毫无察觉。
生成特定的音频信息流,直接进行动态压缩,MD5哈希处理后得到音频指纹

之所以不同设备不同浏览器其音频指纹会有差异是因为主机/浏览器的硬件/软件的细微差别,导致音频信号的处理上的差异,相同机器上的同款浏览器产生相同的音频输出,不同机器或不同浏览器产生的音频输出会存在差异。

此处推荐篇论文,其指纹模型目前能够达到99%的识别率.

论文链接包含敏感词,所以用图片代替

可以看出这三类高级指纹都是利用硬件或软件的差异,有的生成图片有的生成音频,然后计算不同的哈希值作为参考指纹.

推荐学习参考开源项目:

fingerprint.js

Valve/fingerprintjs2

在互联网世界里,各种指纹的碰撞比比皆是,尤其是想mac这样的量产机,同一批次同一型号的mac,使用相同的浏览器就很有可能产生相同的“高级指纹”,存在一定的重复率,这个时候就需要结合上述的所有指纹,经过分析,计算最终的综合指纹作为判断。这样就可以大大降低碰撞率,极大提高客户端唯一性识别的准确性。

版权声明 (原创):本文内容由移动云用户自发贡献,版权归原作者所有,移动云开发者社区不拥有其著作权,亦不承担相应法律责任。如果您发现本社区有涉嫌抄袭的内容,可填写举报信息,一经查实,本社区将立刻删除涉嫌侵权内容。

### 浏览器指纹技术概述 浏览器指纹是一种基于用户设备特征的技术,用于生成几乎唯一的标识符来识别特定用户的访问行为。这种技术利用了多种属性组合而成的信息集合,这些属性被称为准标识符 (quasi-identifier) 属性[^1]。 当多个准标识符属性被综合分析时,它们可以形成一种独特的模式,从而实现对个体的重新识别。以下是具体方法: #### 准标识符属性的作用 单个准标识符属性本身不足以唯一标识某个记录或个人,但如果与其他类似的属性相结合,则可能允许无歧义地重新识别某些个体。例如,在浏览器环境中,常见的准标识符包括但不限于以下几类: - **操作系统版本** - **屏幕分辨率** - **字体列表** - **插件配置** - **HTTP头字段** 通过收集上述信息并将其汇总起来,就可以构建出一个高度个性化的“指纹”,这个指纹能够区分不同的用户及其设备。 #### 实现过程中的关键技术点 为了更清楚地理解如何使用浏览器指纹创建独一无二的用户ID,请考虑以下几个方面: ##### 数据采集阶段 在此期间, 需要尽可能多地获取有关客户端环境的数据项。下面是一些常用的方法和技术: ```javascript // 获取用户代理字符串 const userAgent = navigator.userAgent; // 查询可用硬件并发数(逻辑CPU核心数量) const cpuCores = navigator.hardwareConcurrency; // 列举已安装的语言偏好设置 const languages = navigator.languages; ``` 以上代码片段展示了几个简单的例子,说明开发者可以通过JavaScript轻松读取各种类型的系统参数。当然实际应用中还需要注意隐私保护法规的要求以及道德责任等问题。 ##### 哈希算法的应用 一旦获得了足够的原始数据之后,下一步就是把这些零散的信息转换成固定长度且难以逆向工程的形式——这就是哈希函数发挥作用的地方。MD5或者SHA系列都是不错的选择之一。 ```python import hashlib def create_fingerprint(data_dict): data_string = ''.join([str(value) for value in data_dict.values()]) hash_object = hashlib.sha256(data_string.encode()) hex_dig = hash_object.hexdigest() return hex_dig[:16] # Example usage data = { 'userAgent': 'Mozilla/5.0', 'cpuCores': 8, 'languages': ['en-US', 'zh-CN'] } unique_id = create_fingerprint(data) print(unique_id) ``` 在这个Python脚本里定义了一个`create_fingerprint()`函数用来接收字典形式输入的数据,并返回十六进制表示前16位字符作为最终的结果。这样既保证了一定程度上的匿名性又保留了充分的区别度。 --- ### 结论 综上所述,尽管单独某一项特性无法构成绝对意义上的身份证明材料,但是借助多维度交叉验证的方式确实可以在很大程度上提高精准定位的可能性。值得注意的是,在实施此类方案之前应当仔细权衡利弊关系,并严格遵循当地法律法规关于个人信息处理的规定。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值