基于 H5 Canvas “指纹识别“ 技术 【浏览器指纹 VS Canvas指纹】

哈喽,大家好 我是xy👨🏻‍💻. 作为一名前端开发工程师,应该都用过H5中的canvas吧!!! 但是你真的了解它吗?Canvas '指纹识别'技术又是什么? 本文将由浅入深,带你了解Canvas '指纹识别'技术

什么是 Canvas

Canvas API(画布)是在HTML5中新增的标签用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用JavaScript操作的位图(bitmap)。

Canvas 对象表示一个 HTML 画布元素 <canvas></canvas>。它没有自己的行为,但是定义了一个 API 支持脚本化客户端绘图操作。

Canvas 能做什么

  • 基础图形的绘制
  • 文字的绘制
  • 图形的变形和图片的合成
  • 图片和视频的处理
  • 动画的实现
  • 小游戏的制作

随着互联网的发展,用户对页面的视觉交互有着更高的要求,传统的 web 前端开发无法得到满足,所以利用强大的Canvas绘图能力,可以是网页显示的内容更加的丰富多彩,Canvas 在给用户带来更好的视觉和交互上的体验。

随手绘制一个简单的图形

<!-- html -->
<body>
    <canvas
      id="canvas_xy"
      width="500"
      height="400"
      style="box-shadow: 0 0 20px black"
    >
      当前浏览器不支持 canvas
    </canvas>
  </body>

<!-- js -->
<script type="text/javascript">
  // 获取 canvas 元素对应的 DOM 对象
  var canvas_xy = document.getElementById("canvas_xy");
  // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
  var ctx = canvas_xy.getContext("2d");
  //设置绘制起点
  ctx.moveTo(100, 100);
  //设置绘制下一个点
  ctx.lineTo(200, 200);
  //设置绘制下一个点
  ctx.lineTo(400, 100);
  //结束绘制
  ctx.closePath();
  //设置线的宽度
  ctx.lineWidth = 10;
  //设置绘制的样式
  ctx.strokeStyle = "red";
  //绘制点之间的线路
  ctx.stroke();
  // 设置填充样式
  ctx.fillStyle = "green";
  // 填充当前视图
  ctx.fill();
</script>

效果如下:

已经了解了 Canvas 的基本使用的同学肯定会问,它和指纹识别有什么关系呢? 其实这里说的指纹识别并不是真正的指纹识别技术,而是利用了Canvas 在不同操作系统、不同浏览器上,产生的图片内容不完全相同(我们肉眼是无法区分的)来标识用户。

既然提到 Canvas 指纹,那肯定也会想到浏览器指纹了,这两种有什么区别和关联呢?

别急!!! 一起来看看浏览器指纹Canvas指纹

浏览器指纹

一般情况下,网站或者广告商都想要一种技术可以在网络上精确的定位到每一个个体,这样就可以通过收集这些个体的数据,然后加以分析之后更加精确的去推送广告和其他的一些活动。Cookie 技术是非常受欢迎的一种。当用户访问一个网站时,网站可以在用户当前的浏览器 Cookie 中永久植入一个含有唯一标示符(UUID)的信息,并通过这个信息将用户所有行为(浏览了哪些页面?搜索了哪些关键字?对什么感兴趣?点了哪些按钮?用了哪些功能?看了哪些商品?把哪些放入了购物车等等)关联起来。

而随着网民对个人隐私的重视,Cookie 越来越不受待见。不少安全工具甚至是浏览器都开始允许或引导用户关闭 Cookie 功能,比如很多主流浏览器都有一个“隐私模式浏览”功能。同时,我们可以很方便的使用浏览器的快捷键清除缓存,这样在两次访问的区间也就无法识别是否是同一个用户,这样一来,网站就很难追踪用户行为了。

这个时候浏览器指纹也就应运而生。

如何获取浏览器指纹?

想必大家一定知道浏览器 navigator 对象 吧,通过 navigator 对象我们可以获取到足够的浏览器相关的信息。我们可以直接在浏览器控制台输入 navigator: 输出如下:

其中获取的硬件类型操作系统用户代理系统字体语言屏幕分辨率浏览器插件浏览器扩展浏览器设置时区差地理位置 等众多信息,这些信息可以称之为浏览器的指纹信息

这些指纹信息“类似”人类的身高、年龄等,有很大的冲突概率,只能作为辅助识别。

这些指纹不能对某个人进行唯一性标识,也无法对客户端进行唯一性判定,基于HTML5的诸多高级指纹对此提供了新思路。

HTML5高级指纹: Canvas 指纹:

什么是 Canvas 指纹

从根本上来说,每一种浏览器都会使用不同图像处理引擎,不同的导出选项,不同的压缩等级,所以每一台电脑绘制出的图形都会有些许不同,这些图案可以被用来给用户设备分配特定编号指纹),也就是说可以用来识别不同用户。

那么,如何给我们的网站增加 Canvas指纹 呢?

我们可以通过html5canvas接口,在网页上绘制一个隐藏的画布图像。

值得注意的是,如果用户的设备操作系统浏览器都一样的话,计算出来的 canvas 指纹是一样的。换句话说:canvas 指纹不具备唯一性,要和其他的浏览器指纹相互结合利用来进一步计算出区分度更高的指纹标识。

如何获取 Canvas 指纹

基于 Canvas 绘制特定内容的图片,使用canvas.toDataURL()方法返回该图片内容的base64编码字符串。对于 PNG 文件格式,以块(chunk)划分,最后一块是一段32位的CRC校验,提取这段CRC校验码便可以用于用户的唯一标识

测试结果表明,同一浏览器访问该域时生成的CRC校验码总是不变

可以简单理解为同样的HTML Canvas元素绘制操作,在不同的操作系统不同的浏览器上,产生的图片内容其实是不完全相同的。出现这种情况可能是有几个原因:

  • 在图片格式上,不同 web 浏览器使用了不同的图形处理引擎、不同的图片导出选项、不同的默认压缩级别等。
  • 在像素级别来看,操作系统各自使用了不同的设置和算法来进行抗锯齿和像素渲染操作。
  • 即使是相同的绘图操作,最终产生的图片数据在 hash 层面上依然是不同的。

获取 Canvas 指纹:

<script type="text/javascript">
  function bin2hex(s) {
    var i,
      l,
      o = "",
      n;

    s += "";

    for (i = 0, l = s.length; i < l; i++) {
      n = s.charCodeAt(i).toString(16);
      o += n.length < 2 ? "0" + n : n;
    }

    return o;
  }

  function getUUID(domain) {
    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext("2d");
    var txt = domain;
    ctx.textBaseline = "top";
    ctx.font = "14px 'Arial'";
    ctx.textBaseline = "tencent";
    ctx.fillStyle = "#f60";
    ctx.fillRect(125, 1, 62, 20);
    ctx.fillStyle = "#069";
    ctx.fillText(txt, 2, 15);
    ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
    ctx.fillText(txt, 4, 17);

    var b64 = canvas.toDataURL().replace("data:image/png;base64,", "");
    // window.atob 用于解码使用 base-64 编码的字符串
    var bin = atob(b64);
    var crc = bin2hex(bin.slice(-16, -12));
    return crc;
  }

  console.log(getUUID("公众号:前端开发爱好者"));
</script>

不同浏览器查看获得不同的指纹信息:

如何检测 canvas 指纹?

在线检测地址:https://browserleaks.com/canvas

如何隐藏自己的 canvas 指纹?

随着谷歌浏览器宣布为了保护用户的隐私,跨域请求不再携带cookies。浏览器指纹技术成为追踪用户的热门技术,那有没有办法隐藏我们的 canvas 指纹呢?

目前主要用2种方式:

  1. 安装浏览器插件,谷歌应用商店有随机修改canvas指纹的插件(CanvasFingerprintBlock),其原理是,每次随机往 canvas 画布里面注入一个随机的噪音(人肉眼是看不到的),从而影响图片数据的CRC校验结果。

  2. 类似LoginBox, multilogin 这样的指纹仿关联软件,其原理是:为每个浏览器窗口环境单独分配指纹数据,和第 1 种方式一样,也是往 canvas 画布里面注入一个随机的噪音,只是这个噪音是固定的。

写在最后

公众号前端开发爱好者 专注分享 web 前端相关技术文章视频教程资源、热点资讯等,如果喜欢我的分享,给 🐟🐟 点一个 👍 或者➕关注 都是对我最大的支持。

欢迎长按图片加好友,我会第一时间和你分享前端行业趋势面试资源学习途径等等。

关注公众号后,在首页:

  • 回复面试题,获取最新大厂面试资料。
  • 回复简历,获取 3200 套 简历模板。
  • 回复React实战,获取 React 最新实战教程。
  • 回复Vue实战,获取 Vue 最新实战教程。
  • 回复ts,获取 TypeAcript 精讲课程。
  • 回复vite,获取 精讲课程。
  • 回复uniapp,获取 uniapp 精讲课程。
  • 回复js书籍,获取 js 进阶 必看书籍。
  • 回复Node,获取 Nodejs+koa2 实战教程。
  • 回复数据结构算法,获取 数据结构算法 教程。
  • 回复架构师,获取 架构师学习资源教程。
  • 更多教程资源应用尽有,欢迎关注获取
### 实现 Vue3 浏览器指纹识别 为了在 Vue3 项目中实现浏览器指纹识别,可以通过 JavaScript 获取多种设备和浏览器特征来构建唯一的标识符。这些特征包括但不限于操作系统版本、浏览器类型、屏幕分辨率、已安装的插件、字体列表以及语言设置等[^2]。 #### 使用第三方库简化开发过程 一种高效的方法是利用现有的开源库 `fingerprintjs` 来获取用户的浏览器指纹。此方法不仅减少了自行编写复杂逻辑的需求,还提高了兼容性和准确性。 首先,在 Vue3 项目中安装 FingerprintJS: ```bash npm install @fingerprintjs/fingerprintjs-pro --save ``` 接着,在组件内初始化并调用该服务以获得指纹数据: ```javascript import { onMounted } from 'vue'; import * as fp from '@fingerprintjs/fingerprintjs-pro'; export default { setup() { let fingerprint; const loadFingerprint = async () => { const visitorDataPromise = await fp.load(); const result = await visitorDataPromise.get(); console.log('Visitor identifier:', result.visitorId); fingerprint = result.visitorId; }; onMounted(() => { loadFingerprint(); }); return { fingerprint, }; }, }; ``` 上述代码展示了如何集成 FingerprintJS 到 Vue 组件生命周期钩子函数中,并打印出访客 ID 或者将其存储起来供后续处理使用。 对于更高级的应用场景,还可以考虑自定义采集参数或结合其他技术手段增强安全性与隐私保护措施。例如,通过 H5 Canvas 渲染特定图像并通过其渲染结果进一步混淆实际硬件信息,从而达到一定程度上对抗简单形式的 canvas 指纹追踪的目的[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值