欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > 使用浏览器指纹做设备唯一标志

使用浏览器指纹做设备唯一标志

2025/2/26 14:25:38 来源:https://blog.csdn.net/u013836242/article/details/140686459  浏览:    关键词:使用浏览器指纹做设备唯一标志

背景:

需要做一个登录安全校验功能, 非常用设备登录网站时, 弹出安全验证框进行验证

调研

设备/浏览器唯一标志 ID 调研

背景:

产品要求新登录设备弹出安全验证框, 因此需要标识每一台设备, 但是前端做不到设备级, 只能尝试标识浏览器

方案:

浏览器本地存储直接设置标识

往 localStorage 中存入一个新变量, 值为登录时间 + 随机数, 之后始终不清除此数据, 每次登录时取该数据一起发给后端, 后端判断与数据库中数据是否一致

优点:

  1. 最简单

缺点:

  1. 用户可以通过浏览器控制台自己修改数据
  2. 隐身模式需要重新校验
  3. 本地存储被清除需要重新校验

使用浏览器音频 API 标识客户

https://audiofingerprint.openwpm.com/

搜集浏览器音频播放的特征值, 计算得到唯一标志

优点:

  1. 纯前端实现, 前端直接使用页面上的代码即可实现
  2. 不同版本的 chrome 浏览器生成的标识相同
  3. 隐身模式/清除本地存储, 标识不变

缺点:

  1. 是否有版权问题?
  2. 公司内同一批同配置电脑 + 驱动 + 同一款浏览器, 可能会重复(再加个随机数? 比如时间之类的?)

使用开源库

https://github.com/fingerprintjs/fingerprintjs/

查询浏览器属性(包括并不限于音频, 画布, 字体, 屏幕, 操作系统, 设备名称等信息), 从中计算出标识

优点:

  1. 纯前端实现, 前端直接引用库即可实现
  2. 隐身模式/清除本地存储, 标识不变

缺点:

  1. 不同版本的 chrome 浏览器生成的标识不同
  2. 还是可能会重复(再加个随机数? 比如请求时间之类的?)

使用前者的升级版

开源版和专业版对比: https://dev.fingerprintjs.com/docs/pro-vs-open-source

demo: https://fingerprintjs.com/demo/

优点:

  1. 在服务器端处理所有信息,将浏览器指纹识别与大量辅助数据(IP 地址、访问时间模式、URL 更改等)相结合,能够可靠地对拥有相同设备的不同用户进行重复数据删除,从而实现 99.5% 的识别准确率

缺点:

  1. 调用 api 次数超过 20K/月, 则开始收费

最终代码:

// 生成浏览器指纹, 目前仅使用了 audio api 生成指纹, 参考 https://audiofingerprint.openwpm.com/ 网站源码
export const gen_fingerPrint = (useFullPrint = true) => {return new Promise((resolve, reject) => {try {let shortPrint = '';let fullPrint = '';const context = new (window.OfflineAudioContext || window.webkitOfflineAudioContext)(1, 44100, 44100);const pxi_oscillator = context.createOscillator();pxi_oscillator.type = 'triangle';pxi_oscillator.frequency.value = 1e4;// Create and configure compressorconst pxi_compressor = context.createDynamicsCompressor();pxi_compressor.threshold && (pxi_compressor.threshold.value = -50);pxi_compressor.knee && (pxi_compressor.knee.value = 40);pxi_compressor.ratio && (pxi_compressor.ratio.value = 12);pxi_compressor.reduction && (pxi_compressor.reduction.value = -20);pxi_compressor.attack && (pxi_compressor.attack.value = 0);pxi_compressor.release && (pxi_compressor.release.value = 0.25);// Connect nodespxi_oscillator.connect(pxi_compressor);pxi_compressor.connect(context.destination);// Start audio processingpxi_oscillator.start(0);context.startRendering();context.oncomplete = function (evnt) {let pxi_output = 0;const sha1 = CryptoJS.algo.SHA1.create();for (let i = 0; i < evnt.renderedBuffer.length; i++) {sha1.update(evnt.renderedBuffer.getChannelData(0)[i].toString());}const hash = sha1.finalize();// Fingerprint using DynamicsCompressor (hash of full buffer):fullPrint = hash.toString(CryptoJS.enc.Hex);for (let i = 4500; i < 5e3; i++) {pxi_output += Math.abs(evnt.renderedBuffer.getChannelData(0)[i]);}// Fingerprint using DynamicsCompressor (sum of buffer values):shortPrint = pxi_output.toString();pxi_compressor.disconnect();resolve(`${useFullPrint ? fullPrint : shortPrint}`);};} catch (err) {console.error(err);resolve('');}});
};

补充:

实际开发中, 发现 fingerprintjs 库也用的相似的参数值, 项目的src/sources/audio.ts 中使用的数值与本方法中的数据基本相同,

之后如果要获取其他数据生成指纹, 可参考此项目的 src/source/index.ts , 其顶部引入了很多获取设备信息的方法, 想要啥信息直接去引入文件找

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词