小心!浏览器指纹正在一步一步找到你(上)

3,499 阅读5分钟

我们都知道,网络上的喷子很多,很多喷子仗着藏在互联网之下,发泄着自己的不满。舆论压力,也是如此产生,那么监管部门会考虑如何定位这些舆论制造者。同样,暴露在资本家眼里的我们,就是成为他们广告推广,定点推送的钱包。本期,我们从浏览器指纹的角度,带你体验一下,追踪与反追踪。

浏览器指纹是什么

Wikipedia给出的定义:

A device fingerprint, machine fingerprint or browser fingerprint is information collected about a remote computing device for the purpose of identification. Fingerprints can be used to fully or partially identify individual users or devices even when cookies are turned off.

说的通俗一点就是:浏览器指纹识别是一种非常准确的方法,可以识别唯一的浏览器并跟踪在线活动

再通俗一点:找到你究竟是谁,然后给你一个独一无二的 id

浏览器指纹有什么作用

为什么,浏览器指纹,这么有用,你的数据为什么会有这么多企业买单?

广告与营销

广告商/营销商现在需要定点投放一些广告/优惠活动,但是随机投放有点大海捞针,所以需要定点向指定用户。那么指定用户是如何找到的,首先需要给这些用户一个独一无二的 id,你可以理解为你的身份证,接下来你每次的行为,都会记录在你的身份证信息上。这样,就形成了一个用户画像,接下来,你的用户画像就可以被出售,再通过转化率等其他一系列行为之类就不多说了。

反欺诈/反羊毛

羊毛党,这个名词随着几次大事件,已经逐渐进入大家的视野了。如何对他们进行防范,而让更多的用户可以来参与到活动,真正的把奖品送给想参加的人,成为了各大运营部的难题。唯一 id 的身份信息,对他们来说是非常重要的,防止一个用户多次领奖励。

浏览器指纹实现的方式

下面,我们将正式的进入讲解。

1. Cookie

每一个用户都有一个独一的 cookie,通过 cookie 我们可以辨别出当前这个用户。

但是用户退出/切换浏览器/换个账号,我们就无从下手了。需要更多的方法来弥补缺陷。

2. Canvas Fingerprinting

很多人可能对这个名词不是很理解。老样子,名词解释一下,参考Wikipedia:

When a user visits a page, the fingerprinting script first draws text with the font and size of its choice and adds background colors. Next, the script calls Canvas API’s ToDataURL method to get the canvas pixel data in dataURL format, which is basically a Base64 encoded representation of the binary pixel data. Finally, the script takes the hash of the text-encoded pixel data, which serves as the fingerprint.

翻译成代码语言:

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);

如果你是 chrome79,电脑是 MacOS,大概率你会得到4fd4a5eb

确实,canvas 的指纹是利用了相同的 HTML5 Canvas 元素绘制操作,在不同操作系统、不同浏览器上,产生的图片内容不完全相同;在图片格式上,不同浏览器使用了不同的图形处理引擎、不同的图片导出选项、不同的默认压缩级别等;在像素级别来看,操作系统各自使用了不同的设置和算法来进行抗锯齿和子像素渲染操作。即使相同的绘图操作,产生的图片数据的 CRC 检验也不相同。但是问题来了,这样还是无法有效的区分。

(平行世界) 2. Audio Fingerprinting

在另外一个平行世界中,有人发现可以通过 Audio Fingerprinting 来进行判定,于是我在冥冥之中感知了,但是具体实现就靠各位灵感了(没找到代码)

(平行世界) 2.1 方法 1

上图显示了如何使用AudioContext属性对音频堆栈进行指纹识别。首先,使用OscillatorNode生成三角波。该信号通过AnalyserNodeScriptProcessorNode传递。最后,将信号通过增益设为零的 GainNode 传递到 A 中,以在连接到AudioContext目标(例如计算机扬声器)之前使任何输出静音。AnalyserNode提供对音频信号的快速傅立叶变换(FFT)的访问,该快速傅立叶变换是使用ScriptProcessorNode添加的onaudioprocess事件处理程序捕获的。所得的 FFT 被馈入哈希并用作指纹。

(平行世界) 2.2 方法 2

上图显示了使用OfflineAudioContext属性对音频堆栈进行设备指纹识别。首先,使用OscillatorNode生成正弦波。输出信号连接到DynamicsCompressorNode,以增加系统之间处理的音频的差异。该压缩器的输出传递到OfflineAudioContext的缓冲区。然后,将来自缓冲区的值之和的哈希值用作指纹。

3. Complex Fingerprinting

正如刚刚所述,很多情况下,重复率会很高,所以,需要很多额外的参数参与计算。比如: UA. IP. Font-size. Font-family ...

fingerprintjs2

fingerprintjs2 传送门

import Fingerprint2 from "fingerprintjs2";

function getUid() {
  return new Promise((resolve, reject) => {
    try {
      if (window.requestIdleCallback) {
        requestIdleCallback(function() {
          Fingerprint2.get(function(components) {
            const values = components.map(component => component.value);
            resolve(Fingerprint2.x64hash128(values.join(""), 31));
          });
        });
      } else {
        setTimeout(function() {
          Fingerprint2.get(function(components) {
            const values = components.map(component => component.value);
            resolve(Fingerprint2.x64hash128(values.join(""), 31));
          });
        }, 500);
      }
    } catch (err) {
      console.error(err);
      reject(exceptGetUid());
    }
  });
}

(async () => {
  const uid = await getUid();
  console.log(uid);
})();

如此你就会得到一个不一样的 uid 了。

4. (Cross-)Browser Fingerprinting via OS and Hardware Level Features

找到了一篇论文,奈何我英文不大行。放个传送门,你们自己去看吧。

(Cross-)Browser Fingerprinting via OS and Hardware Level Features

总结

本次我们带领大家了解了,什么是浏览器指纹,以及如何实现一个浏览器指纹。好了,先讲到这里把,我是 ihap 技术黑洞的 肥少,下期再见

参考文献