文章内容
2017/9/1 9:03:15,作 者: 黄兵
浏览器指纹-取代cookie的网站追踪技术
什么是“指纹”?
说到“指纹”可能大家都知道是手指头的纹理,而且每个人的指纹都是唯一的。 如果你时常接触信息安全领域的一些资料,也会听到“指纹”这个形象的说法(比如:操作系统指纹、网络协议栈指纹、等等)。IT 领域提到的“指纹”一词,其原理跟“刑侦”是类似的——“当你需要研究某个对象的类型/类别,但这个对象你又无法直接接触到。这时候你可以利用若干技术来获取该对象的某些特征,然后根据这些特征来猜测/判断该对象的类型/类别。”
什么是“指纹”的“信息量”?
在 IT 领域有各种各样的特征可以用来充当“指纹”。这时候就需要判断,用哪个特征做指纹,效果更好。为了讨论这个问题,就得扫盲一下“指纹的信息量”。 为了帮助大伙儿理解,先举一个例子: 假设你要在学校中定位某个人,如果你光知道此人的性别,你是比较难定位的(只能排除 1/2 的人);反之如果你不知道性别,但是知道此人的生日,就比较容易定位(可以排除掉大约 364/365 的人,只剩大约 1/365 的人)。为什么?因为“生日”比“性别”更加独特,所以“生日”比“性别”能够提供更多的信息量。 从这个例子可以看出:某个特征越独特,则该特征的信息量越大;反之亦然。信息量越大的特征,就可以把对象定位到越小的范围。
“指纹”的“信息量”如何度量——关于指纹的比特数?
(本节涉及到中学数学,数学很差的或者对数学有恐惧感的读者,请直接无视) 在 IT 领域中,可以用【比特数】来衡量某个指纹所包含的信息量。为了通俗起见,先以前面提到的“性别”来说事儿。性别只有两种可能性——“男”或者“女”,并且男女的比例是大致平均的。所以,当你知道了某人的性别,就可以把范围缩小到原先的 1/2。用 IT 的术语来讲,就是:“性别”这个特征只包含一个比特的信息量。以此类推:
- 当我们说:“某特征包含3比特信息量”,意思就是:该特征会有8种大致平均的可能性(8等于2的3次方)。一旦知道该特征,可以把目标定位到八分之一。
- 当我们说:“某特征包含7比特信息量”,意思就是:该特征会有128种大致平均的可能性(128=2^7)。一旦知道该特征,可以定位到 1/128。
再来说“生日”。(不考虑闰年的情况下)生日有365种可能性(并且也是平均分布的),所以生日包含的比特数大约是 8.51。为什么是 8.51 捏,因为 2 的 8.51 次方 约等于 365。因此,知道了某人的生日就可以把范围缩小到 1/365 通过上述举例,大伙儿对于指纹的信息量,应该有一些粗浅的认识了吧?
多个指纹的综合定位
如果能同时获取【互不相关】的若干个指纹,就可以大大增加定位的精确性。 比如要在某个公司里面定位某人,如果你知道此人的“生日”和“生肖”,那么就可以达到 1/4380(1/4380 = 1/12 * 1/365) 的定位精度。因为综合定位之后,比例之间是【乘法】的关系,所以范围就被急剧缩小了。 为什么要特别强调“互不相关”呢?假如你同时知道的信息是“生日”和“星座”,那么定位的精度依然是 1/365——因为生日的信息已经包含了星座的信息。所以,只有那些相互独立的特征(所谓的相互独立,数学称为“正交”),在综合定位的时候才可以用【乘法】。
什么是“浏览器的指纹”?
当你使用浏览器访问某个网站的时候,浏览器【必定会暴露】某些信息给这个网站。为什么强调“必定”呢?因为这些信息中,有些是跟 HTTP 协议相关的(本章节说的 HTTP 协议是广义的,也包括 HTTPS)。只要你基于 HTTP 协议访问网站,浏览器就【必定】会传输这些信息给网站的服务器。 再罗嗦一下:HTTP 协议是 Web 的基石。只要你通过浏览器访问 Web,必定是基于 HTTP 协议的。因此,Web 网站的服务器必定可以获取到跟你的浏览器相关的某些信息(具体是哪些信息,下面会说到)。
“浏览器指纹”如何暴露隐私?
“浏览器指纹”的机制跟 cookie 有点相似。 对于“浏览器指纹”导致的隐私问题,这里举2个例子来说明其危害。
对于无需登录的网站
如果你的浏览器允许记录 cookie,当你第一次访问某网站的时候,网站会在你的浏览器端记录一个 cookie,cookie 中包含某个“唯一性的标识信息”。下次你再去访问该网站,网站服务器先从你的浏览器中读取 cookie 信息,然后就可以根据 cookie 中的“唯一标识”判断出,你之前曾经访问过该网站,并且知道你上次访问该网站时,干了些什么。对付这种 cookie 很简单,你只需要在前后两次访问之间,清空浏览器的 cookie,网站就没法用 cookie 的招数来判断你的身份。 但是“清空 cookie”这招对“浏览器指纹”是无效滴。比如说你的浏览器具有非常独特的指纹,那么当你第一次访问某网站的时候,网站会在服务器端记录下你的浏览器指纹,并且会记录你在该网站的行为;下次你再去访问的时候,网站服务器再次读取浏览器指纹,然后跟之前存储的指纹进行比对,就知道你是否曾经来过,并且知道你上次访问期间干了些什么。
对于需要登录的网站
假如网站没有采用“指纹追踪”的技术,那么你可以在该网站上注册若干个帐号(马甲)。当你需要切换身份的时候,只需要先注销用户,清空浏览器的 cookie,然后用另一个帐号登录。网站是看不出来的。
“浏览器指纹”比“cookie”更隐蔽,更危险
刚才对比了“浏览器指纹”和“cookie”两种身份追踪技术。两者的原理类似——都是利用某些特殊的信息来定位你的身份。两者的本质差异在于:
- cookie 需要把信息保存在浏览器端,所以会被用户发现,也会被用户清除。
- 而“浏览器指纹”无需在客户端保存任何信息,不会被用户发觉,用户也无法清除(换句话说:你甚至无法判断你访问的网站到底有没有收集浏览器指纹)。
“浏览器指纹”包含哪些信息?
浏览器暴露给网站的信息有很多种,常见的有如下几种:
User Agent
关于 User Agent 是什么,已经在本系列前面的博文中有简单的说明,已了解的同学可以继续往下看。
屏幕分辨率
这个比较通俗易懂。稍微补充一下:这一项不仅包括屏幕的尺寸,还包括颜色深度(比如你的屏幕是16位色、24位色、还是32位色)。
时区
这个也比较通俗。我们应该都是“东8区”。
浏览器的插件信息
也就是你的浏览器装了哪些插件。 再罗嗦一次:浏览器的“插件”和“扩展”是两码事儿,别搞混了。
浏览器的字体信息
和浏览器相关的一些字体信息。 如果你的浏览器安装了 Flash 或 Java 插件,有可能会暴露某些字体信息。
HTTP ACCEPT
这是 HTTP 协议头中的一个字段。考虑到列位看官大都不是搞 IT 技术的,这里就不深入解释这项。
其它
以上就是常见的浏览器指纹。当然啦,还有其它一些信息也可以成为“浏览器指纹”,考虑到篇幅就不一一列举并解释了。有兴趣的同学,请自行阅读 Mozilla 官网的文档。
一般情况下,网站或者广告联盟都会非常想要一种技术方式可以在网络上精确定位到每一个个体,这样可以通过收集这些个体的数据,通过分析后更加精准的去推送广告(精准化营销)或其他有针对性的一些活动。Cookie技术是非常受欢迎的一种。当用户访问一个网站时,网站可以在用户当前的浏览器Cookie中永久植入一个含有唯一标示符(UUID)的信息,并通过这个信息将用户所有行为(浏览了哪些页面?搜索了哪些关键字?对什么感兴趣?点了哪些按钮?用了哪些功能?看了哪些商品?把哪些放入了购物车等等)关联起来。
而随着网民对个人隐私的重视,Cookie越来越不受待见。不少安全工具甚至是浏览器都开始允许或引导用户关闭Cookie功能,比如很多主流浏览器都有一个“隐私模式浏览”功能。这样以来,网站就很难追踪用户行为了。但仍然有一些方法可以让网站去追踪每一个访问者的行为,比如通过flash cookie的方式也可以达到唯一标识和追踪的目的。
于是在网上找资料查阅,发现了一个以前从未了解过的技术:浏览器指纹(帆布指纹技术)
第一种:fingerprint.js
var fp1 = new Fingerprint().get();
var fp2 = new Fingerprint({ ie_activex: true }).get();
var fp3 = new Fingerprint({ screen_resolution: true }).get();显示为:
fp1指纹值
1699100748
fp2指纹值:通过检测浏览器安装的插件
443685597
fp3指纹值:通过屏幕分辨率
143346620
经过测试总结:
在火狐 遨游 谷歌浏览器中,fp1和fp2的值总是保持同浏览器值一样
在ie8以及以上版本中,这三个值都是不同的
然而,在ie7和ie5中,fp2和fp3都会对应一致,然后用同事的机子测试,发现不同机子的ie7和ie5的值始终一样,这就没法识别为客户端唯一的依据了。
于是尝试用第二种方式
var options = { swfPath: '/assets/FontList.swf', excludeUserAgent: true };
new Fingerprint2(options).get(function (result) { alert(result)}fp1指纹值
baddaa50d021c540aff9b2ad
这种方式pc端测验没有发现同样的,但是在办公室找同事 用苹果手机6s测试 出现了重复的
又找了第三种方式
var client = new ClientJS();
document.getElementByIdx_x_x_x_x_x('fp4').innerHTML = client.getFingerprint();
document.getElementByIdx_x_x_x_x_x('fp5').innerHTML = client.getCustomFingerprint();测试结果:
getFingerprint:ie 7和ie5跟第一种情况一样,ie8以上版本还是可以保持唯一性 ,手机测试也有出现重复的
getCustomFingerprint:所有机子所有浏览器的值都是一模一样 无参考价值
第四种
从第二种而来 换一个
var fp = new Fingerprint2();
fp.get(function (result) {
document.getElementByIdx_x_x_x_x_x('fp1').innerHTML=result;
});相对来说 经测试这个方式的唯一性好一点点,第二种方式ie8 ie7 ie5都是一样
相关文件参考:http://trends.builtwith.com/javascript/fingerprint
评论列表