?‍? 写在开头

点赞 + 收藏 === 学会???

什么是浏览器指纹?

浏览器指纹,是用来唯一标识你浏览器的一组“特征值”。它不是我们理解中的那种真实指纹,而是通过收集浏览器、操作系统、设备分辨率、字体、插件等信息,组合成的一个独特 ID。

和传统的 Cookie 不同,浏览器指纹不需要在用户设备上存储任何东西,完全是“读取现有信息”来识别用户。

使用背景

在最近的项目中,有个小需求:想用用户的设备作为唯一凭证,来验证身份

一开始我想着简单粗暴点,用 JS 获取手机的 IMEI 或 PC 的序列号。但查了下资料后才发现,这根本行不通——JS 根本没权限访问这些底层硬件信息,安全机制早就把这条路堵死了。

后来才反应过来,我真正想要的,是一个“设备唯一标识”,也就是——浏览器指纹。

可行方案

查阅了一些资料之后,目前比较常见的几种浏览器指纹方案如下:

  • Navigator 指纹:浏览器类型、版本、系统平台等信息。
  • Canvas 指纹:让浏览器绘制一段隐藏的图像,然后读取图像的像素差异,不同设备会有微小区别。
  • WebGL 指纹:利用显卡和图形驱动渲染差异,获取设备的唯一特征。
  • 字体、插件、时区、屏幕分辨率等:这些信息组合起来也能提供一定的识别度。

当然,单一方案识别率可能不高,但多种信息结合后,指纹的唯一性就会明显提升。

Navigator 指纹

Navigator 是前端获取浏览器和部分设备环境信息的重要接口。

下面是一些常用的属性和方法(跨浏览器兼容性较好的为主):

企业微信截图_20250807180856

企业微信截图_20250807180907

 偷个懒,让Tare直接帮我写个Navigator 指纹示例吧。

企业微信截图_20250807180918

 

<!DOCTYPE html><html><head>    <title>Navigator 指纹示例</title></head><body>    <h2>Navigator 指纹示例</h2>    <pre id="output"></pre>    <script>        async function getNavigatorFingerprint() {            // 收集 navigator 相关信息            const data = {                userAgent: navigator.userAgent,                platform: navigator.platform,                language: navigator.language,                languages: navigator.languages,                cookieEnabled: navigator.cookieEnabled,                hardwareConcurrency: navigator.hardwareConcurrency || 'N/A',                deviceMemory: navigator.deviceMemory || 'N/A',                webdriver: navigator.webdriver || false,            };            // 将数据转成字符串            const dataString = JSON.stringify(data);            // 计算 SHA-256 哈希            const hashBuffer = await crypto.subtle.digest(                "SHA-256",                new TextEncoder().encode(dataString)            );            // 转成十六进制字符串            const hashArray = Array.from(new Uint8Array(hashBuffer));            const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');            return { data, fingerprint: hashHex };        }        getNavigatorFingerprint().then(result => {            const output = document.getElementById('output');            output.textContent =                "采集到的 Navigator 信息:n" + JSON.stringify(result.data, null, 2) +                "nn生成的指纹(SHA-256):n" + result.fingerprint;        });    </script></body></html>

代码生成完毕,点击应用直接预览:

企业微信截图_20250807180931

经过测试,在同一个电脑上,这个指纹是稳定的,多次执行,这个值不会变。

但这这个指纹明显有缺陷,我系统语言或者浏览器升级后,这个指纹肯定会改变。

Canvas 指纹

由于不同设备(包括操作系统、显卡、驱动、字体渲染引擎等)在绘制同一段 Canvas 内容时会存在细微差异,最终得到的图像数据(通常是像素或转成 base64)在不同设备上往往是不同的。

这些细微差异生成的哈希值就是“指纹”,由于只与设备性能有关,指纹稳定性显然比Navigator 指纹高一些。

企业微信截图_20250807180941

 

<!DOCTYPE html><html><head>    <title>简单Canvas指纹示例</title></head><body>    <h2>简单Canvas指纹示例</h2>    <p>请打开控制台(F12)查看结果</p>    <script>        // 创建一个简单的Canvas指纹生成函数        function generateCanvasFingerprint() {            // 创建canvas元素            const canvas = document.createElement('canvas');            canvas.width = 200;            canvas.height = 100;                        // 获取绘图上下文            const ctx = canvas.getContext('2d');                        // 填充背景            ctx.fillStyle = 'white';            ctx.fillRect(0, 0, canvas.width, canvas.height);                        // 绘制一些图形和文字            // 绘制红色矩形            ctx.fillStyle = 'red';            ctx.fillRect(20, 20, 50, 50);                        // 绘制蓝色圆形            ctx.fillStyle = 'blue';            ctx.beginPath();            ctx.arc(120, 45, 25, 0, Math.PI * 2);            ctx.fill();                        // 绘制文本            ctx.fillStyle = 'black';            ctx.font = '16px Arial';            ctx.fillText('Canvas指纹', 60, 80);                        // 获取canvas数据URL            const dataURL = canvas.toDataURL();                        // 简单哈希函数            function simpleHash(str) {                let hash = 0;                for (let i = 0; i < str.length; i++) {                    const char = str.charCodeAt(i);                    hash = ((hash << 5) - hash) + char;                    hash = hash & hash; // 转换为32位整数                }                return hash.toString(16); // 转换为16进制            }                        // 计算指纹            const fingerprint = simpleHash(dataURL);                        return {                fingerprint: fingerprint,                dataURL: dataURL            };        }                // 生成并输出指纹        const result = generateCanvasFingerprint();        console.log('Canvas指纹:', result.fingerprint);        console.log('Canvas数据URL前100个字符:', result.dataURL.substring(0, 100) + '...');                // 如果浏览器支持更安全的哈希算法,也可以使用它        if (window.crypto && window.crypto.subtle) {            const encoder = new TextEncoder();            const data = encoder.encode(result.dataURL);                        window.crypto.subtle.digest('SHA-256', data)                .then(hashBuffer => {                    // 将哈希缓冲区转换为十六进制字符串                    const hashArray = Array.from(new Uint8Array(hashBuffer));                    const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');                                        console.log('Canvas指纹(SHA-256):', hashHex);                });        }    </script></body></html>
生成的指纹还是很不错的。

企业微信截图_20250807180952

 其他几种方式生成浏览器指纹都大同小异,这里就不介绍了。

 

本文转载于:https://jueji*n.*c*n/post/7511915154032853018

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]