一、什么是浏览器指纹?

“浏览器指纹”是指通过收集用户设备的特征标识,用来对用户进行唯一性识别、跟踪、分析行为、所生成的摘要ID。网站通过收集大量的信息,然后对所有的特征标识进行并集匹配,可以十分精确的对用户进行标记。

标识内容: UA,语言,时区,地理位置,分辨率,webRTC,Cookie,字体指纹,Canvas,WebGL,WebGL Info,AudioContext,SpeechVoices,媒体设备,CPU参数,内存参数,OS,索引数据库,Resolution等等。

二、信息熵与指纹

信息熵是指消息中含有的信息量。熵越高,则能传输越多的信息,熵越低,则意味着传输的信息越少。

举例:某中学每个年级都有10个班,每个班的人数相同。现在得知A同学是三年二班的学生,那该消息的的熵便是4.91bit左右(log(30, 2));如果又得知A同学生日在5月份,那这条消息的熵约为3.58bit左右(log(12, 2));最后得知A同学其实是女生而不是男生,那又获得了一条1bit熵的消息。每条消息的熵虽然不高,但是三条消息的熵加起来有9.49bit,或者说,同时具有这三个特征的学生,在该中学里平均每720个人才有一个。

在网上冲浪的过程中,浏览器向网站服务器发出请求,网站服务器根据请求内容响应。在浏览器与网站服务器的交互中,浏览器会向网站暴露许多不同消息,比如最简单的User-Agent 里就包含了浏览器型号、版本、操作系统等信息。正如人的指纹可以用来识别不同的人一样,当浏览器暴露的信息的熵足够高时,这些信息就可以用来识别、追踪用户。

举例:在某网络论坛发布帖子,发完之后清空浏览器Cookie和缓存,重启网络,并且使用代理工具再次访问该网络论坛,更换一个新的用户马甲回复刚发布的帖子。即使如此操作,网络管理员还是有可能知道回帖的用户和发帖的用户其实是同一个人。

三、浏览器指纹的用途

对于网站而言,拿到浏览器指纹并没有实际价值,真正有价值的是这个浏览器指纹对应的用户信息。作为网站站长,收集用户浏览器指纹并记录用户的操作,是一个有价值的行为,特别是针对没有用户身份的场景。例如在一个内容分发网站上,用户A喜欢浏览二次元相关的内容,通过浏览器指纹记录这个兴趣,那么下次用户不需要登录即可向A用户精准推送二次元相关的信息。在信息爆炸的当下,这是一种优秀的内容分发方式。
对于用户而言,建立个人上网行为与浏览器指纹之间的联系或多或少都有侵犯用户隐私的意味,特别是将用户的浏览器指纹和真实的用户信息相关联起来时。

四、浏览器指纹的发展背景

  • 第一代是状态化的,主要集中在用户的cookie和evercookie上,需要用户登录才可以得到有效的信息。

  • 第二代才有了浏览器指纹的概念。通过JS获取操作系统、分辨率、像素比等信息上传到后台归并。根据收集的特征值从而让用户更具有区分度(例如UA、浏览器插件信息)。第二代指纹追踪技术唯一性可以保证,但准确率很难完全保证。主要原因就是在跨浏览器指纹识别上面。跨浏览器之后,第二代技术中很重要的 canvas 指纹、浏览器插件指纹都变了,所以很难把跨浏览器指纹归并到同一设备上。因为设备指纹相同,很大概率上是同一台设备;但是,设备指纹不同时,不一定不是同一台设备。

  • 第三代主要将目光放在用户本身上,通过收集上网行为、习惯来为用户建立特征值甚至模型(画像),以求实现真正的追踪技术,这部分目前实现比较复杂,仍在探索中。

总结:第一代、第二代的指纹追踪技术是直接通过JS收集信息,第三代指纹追踪技术目前可看到的案例是2017年RSA创新沙盒的冠军unifyid技术。目前处于2.5代是因为还在解决跨浏览器识别指纹的问题。

五、浏览器指纹的采集

浏览器指纹是由许多浏览器的特征信息综合起来的,其中特征值的信息熵也是不尽相同。常见可行的特征值如下:

1.HTTP Header:这是最基本的信息。使用开发者工具可以看到浏览器在请求一个网页时到底发送了哪些header。目前很少有网站会读取并使用这个header(例如Google就是无视header,而是根据 IP 地址判断国家,进而决定网页的语言)。User-Agent里则包含了浏览器信息和操作系统信息。

2.语言,时区,地理位置,分辨率,字体指纹,这几个是用户根据IP和电脑的使用场景进行设置,来模仿真实环境。

3.Cookie:主要是用于方便快速登录一些网站,主要承载登录信息和网站相关信息的文档。

4.webRTC指纹:是可以让浏览器有音视频实时通信的能力,它提供了三个主要的API来让JS可以实时获取和交换音视频数据,MediaStream、RTCPeerConnection和RTCDataChannel。当然如果要使用WebRTC获得通信能力,用户的真实ip就得暴露出来(NAT穿透),所以RTCPeerConnection就提供了这样的API,直接使用JS就可以拿到用户的IP地址。

5.canvas指纹:是HTML5中的动态绘图标签,也可以用它生成图片或者处理图片。即便使用Canvas绘制相同的元素,但是由于系统的差别,字体渲染引擎不同,对抗锯齿、次像素渲染等算法也不同,canvas将同样的文字转成图片,得到的结果也是不同的。

6.WebGL指纹:是一种JavaScript浏览器API,用于在网页上呈现3D图像。网站可利用WebGL来识别您的设备指纹。通常网站可以用两种方法做到这一点:

7.AudioContex指纹:和Canvas类似也是基于硬件设备或者软件的差别,来产生不同的音频输出,然后计算得到不同的hash来作为标志,当然这里的音频并没有直接在浏览器中播放出来,只需要拿到播放前的处理数据就行,音频指纹测试地址

8.Do Not Track:在http头部可以声明这样一个标志“DNT”意味“Do Not Track”,如果值为1表示为不要追踪我的网页行为,0则为可以追踪。即便没有cookie也可以通过这个标志符告诉服务器我不想被追踪到,不要记录我的行为。

9.CPU内核数量:这个在之前的设备指纹方案中都是没有使用到的,现代浏览器可以用navigator .hardware Concurrency来获取。如果不支持这个方法,则可以利用另一种方式获取,当增加Web Worker的数量时,可以监视payload的完成时间。当计算量达到一定的程度,Web Woker完成payload的时间显著增加,达到硬件并发的限制,从而判断核心的数量。一些浏览器(如Safari)会将Web Workers的可用内核数量减少一半,所以在获取跨浏览器指纹时,我们需要将获取到的核心数量加倍。
10.媒体设备,内存参数这些参数是电脑和浏览期相关指纹。

六、如何隐藏浏览器指纹?

浏览器指纹是浏览器的固有属性,哪怕你的浏览器不发送 UA、禁用各种现代浏览器技术、禁用 JavaScript,“没有指纹”反而成了最可疑的指纹,因为在成千上万的用户里,你的浏览器是唯一没有指纹的,自然就鹤立鸡群了。

最好的方法是大隐隐于市,让浏览器指纹变得大众化。比如现在市面上最流行的操作系统和浏览器组合是 Windows 10 + Google Chrome,那你就使用这一组合。如果你想连屏幕大小、时区等信息一并模拟,甚至可以装个虚拟机来上网(目前并没有有效可靠的从网页上检测浏览器是否运行在虚拟机里的技术,如果有的话,那运行在虚拟机里反而也会成为鹤立鸡群的特征)。对于一般用户来说,使用最流行的操作系统和浏览器组合进行上网冲浪已经足够“大隐隐于市”了,但是对于一些注重网络隐私的用户来说,还需要更多的措施。