fingerprint2 计算浏览器指纹分析
介绍
浏览器指纹简单来说就是获取浏览器一些具有辨识度的信息,计算得到的值,以此指纹信息可以对应此用户。辨识度的信息可以是 UA、时区、地理位置或者是你使用的语言等其他的参数,信息越多并且信息的区别度越大,越能决定浏览器指纹的准确性。
直接使用 fingerprint2 库
<script src="https://cdnjs.cloudflare.com/ajax/libs/fingerprintjs2/2.1.0/fingerprint2.js"></script>
<script>
requestIdleCallback(function () {
Fingerprint2.get(function (components) {
console.log(components) // an array of components: {key: ..., value: ...}
var values = components.map(function (component) { return component.value })
console.log(values);
var hash = Fingerprint2.x64hash128(values.join(''), 31)
console.log(hash)
})
})
</script>
计算了这么 29 个浏览器指征,能得到一个 32 个字符串(128位)的字符串,据说识别率能有 99.9% 据介绍 我不禁对他是怎么做的感到好奇
分析
信息熵(entropy)是接收的每条消息中包含的信息的平均量,熵越高,则能传输越多的信息,熵越低,则意味着传输的信息越少。
图片摘自 掘金-是熊大啊-浏览器指纹追踪技术简述,下图就是数个特征值的信息熵、重复概率和具体的值:
可见 UA,ACCEPT Headers,canvas 的熵值都很高,重复率也小。
canvas
Hash of canvas fingerprint 的信息熵最大有 15.8,按上图所示,并且平均每 56922 个浏览器才会出现一个一样的值。
使用 Canvas 绘制相同的元素,但是由于系统的差别,字体渲染引擎不同,对抗锯齿、次像素渲染等算法也不同,canvas 将同样的文字转成图片,得到的结果也是不同的。
获取 Hash 的代码简化如下
function getCanvasFingerprint () {
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
var context = canvas.getContext("2d");
context.font = "18pt Arial";
context.textBaseline = "top";
context.fillText("Hello, user.", 2, 2);
return canvas.toDataURL("image/jpeg");
}
getCanvasFingerprint()
我分别再 Chrome 和 Edge 上运行
可以再 ,可以点击这里测试一下你Canvas指纹。我测试的结果碰撞率约莫 0.05%。
258 of 528769 user agents have the same signature
当然 fingerprintjs2 计算 canvas 的代码更完善,请参照fingerprintjs2 的 getCanvasFp 方法 ,笔者测试按照他生成的 dataUrl 有 33.4kb。
怎么计算?
上文 Fingerprint2 的调用,能窥见一些信息,把所有的指征包括 UA,ACCEPT Headers,canvas 等其他 29 项都直接拼接成一个字符串传给了 Fingerprint2.x64hash128 方法,
分析其方法,使用了 MurmurHash3 哈希算法,笔者查阅得知我们熟知的 MD5、SHA1 是加密哈希算法,而 MurmurHash3 是非加密的哈希算法。如果数据量小,或者不太在意哈希碰撞概率,甚至希望生成的哈希值更小,都推荐使用非加密的哈希算法。有 128 位和 32 位两个版本,128 位版本的运算速度是 MD5 的十倍,此方法就选了 128 位的。
去 MurmurHash online 在线计算一下从 Fingerprint2 那边得到的指征拼接字符串
结果和上文的 Fingerprint2 运算结果一致
思考
这么计算在同一机器的不同浏览器得到的 hash 不一致,那么跨浏览器的指纹识别怎么做,请参照这篇 http://yinzhicao.org/TrackingFree/crossbrowsertracking_NDSS17.pdf