作者:中国移动云能力中心 ——谢雷
概要:我们在日常网络冲浪的时候,肯定都有过这样的经历: 在某东/某宝上浏览过电动牙刷后,再访问其他网站时总会在边角看到大大小小类似的商品广告。 文章主要分享如何生成浏览器指纹,用以精准定位用户。
“浏览器指纹”是一种通过浏览器对网站可见的配置和设置信息来跟踪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);
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);
...
3)音频指纹
音频上下文借助OS和音频卡中的音频堆栈,为音频信号产生到信号滤波,提供处理功能。具体来说,现有的指纹识别工作使用振荡器节点生成三角波,然后将波馈入产生压缩效果的信号处理模块,该节点可以抑制较大的声音以及放大微小的声音。 然后,经处理的音频信号通过分析节点转换为频域。
这种波形在同一台机不同浏览器是不一样的.但是对于跨浏览器,其峰值和它们对应的频率相对稳定.通过映射关系可以将这个作为跨浏览器的特征.其中作为特征的有采样率,最大通道数,输入数,输出数,通道数,通道计数模式和通道解释。
HTML5提供给JavaScript编程用的Audio API则让开发者有能力在代码中直接操作原始的音频流数据,对其进行任意生成、加工、再造,诸如提高音色,改变音调,音频分割等多种操作,甚至可称为网页版的Adobe Audition。
其大致原理如下,方法有二:
生成特定的音频信息流,对其进行一系列操作后,计算SHA值作为指纹,音频输出到音频设备之前进行清除,用户毫无察觉。
生成特定的音频信息流,直接进行动态压缩,MD5哈希处理后得到音频指纹
之所以不同设备不同浏览器其音频指纹会有差异是因为主机/浏览器的硬件/软件的细微差别,导致音频信号的处理上的差异,相同机器上的同款浏览器产生相同的音频输出,不同机器或不同浏览器产生的音频输出会存在差异。
此处推荐篇论文,其指纹模型目前能够达到99%的识别率.

论文链接包含敏感词,所以用图片代替
可以看出这三类高级指纹都是利用硬件或软件的差异,有的生成图片有的生成音频,然后计算不同的哈希值作为参考指纹.
推荐学习参考开源项目:
在互联网世界里,各种指纹的碰撞比比皆是,尤其是想mac这样的量产机,同一批次同一型号的mac,使用相同的浏览器就很有可能产生相同的“高级指纹”,存在一定的重复率,这个时候就需要结合上述的所有指纹,经过分析,计算最终的综合指纹作为判断。这样就可以大大降低碰撞率,极大提高客户端唯一性识别的准确性。
版权声明 (原创):本文内容由移动云用户自发贡献,版权归原作者所有,移动云开发者社区不拥有其著作权,亦不承担相应法律责任。如果您发现本社区有涉嫌抄袭的内容,可填写举报信息,一经查实,本社区将立刻删除涉嫌侵权内容。
浏览器指纹技术详解:Canvas、WebGL与Audio指纹
文章介绍了浏览器指纹的生成原理,包括普通指纹和高级指纹。重点讲述了Canvas指纹、WebGL指纹和Audio音频指纹的生成过程及其实现代码,强调这些高级指纹在提高客户端唯一性识别准确性上的作用。
1188

被折叠的 条评论
为什么被折叠?



