浏览器指纹
技术简介:通过收集和分析用户浏览器和设备的各种属性来生成唯一标识符(指纹)的技术,主要应用于识别和追踪用户。
开源库
- fingerprintjs https://github.com/fingerprintjs/fingerprintjs
- thumbmarkjs https://github.com/thumbmarkjs/thumbmarkjs
- creepjs https://github.com/abrahamjuliot/creepjs
- Broprint.js https://github.com/Rajesh-Royal/Broprint.js
开源库比较
| 库名称 | 优点 | 缺点 | 备注 |
|---|---|---|---|
| FingerprintJS | 1. 客户端指纹计算 2. 跨端、跨平台、多浏览器内核指纹场景 | 1. 源码维护难度大 | 跨端跨平台场景推荐使用 |
| Fingerprint Pro | 1. 云服务来处理和存储数据 2. 数据分析和欺诈检测 3. 官网介绍识别率可达95% | 1. 付费 2. 存在数据泄露风险 | 识别率要求、安全要求高的场景 |
| thumbmarkjs | 1. 客户端指纹计算 2. 基础指纹场景 3. 维护简单 | 1. 无服务端依赖 | 适合目前业务,推荐使用 |
| creepjs | 1. 客户端+服务端辅助指纹计算 2. 服务端提供可疑检测、行为追踪 | 1. 需要接入第三方服务 2. 存在数据泄露风险 | 识别率,安全性相对较高 |
| Broprint.js | 1. 轻量级指纹计算库(canvas、音频) | 1. 重复率较高 | 轻量级 |
前端指纹不是绝对安全和100%不重复,客户端指纹计算识别率 40%~60%,通过服务端辅助计算、反欺诈服务,识别率可达95%。
反欺诈: 1、纯客户端做不到绝对防重和反欺诈技术,必须配合服务端能力。 2、反欺诈主要是通过收集更多用户的行为,依靠算法、机器学习分析用户行为,配合ip地址,检测用户是否有可疑行为。
金融业务方案选择
基于金融业务:
- 大多数集中在PC端。
- 主要用户使用chrome、360等chrome内核浏览器,所以对跨平台场景依赖较低。
- 金融数据的重要性,不能暴漏数据到外部。
- 前期要求便于维护,简单接入,后续根据业务迭代。
- 指纹计算初期会使用 thumbmarkjs 提供的所有指标。
所以,推荐使用 thumbmarkjs 库进行二次开发,封装适合金融 PC 业务的浏览器指纹 npm 通用库。
浏览器指纹计算指标
thumbmarkjs
| 参数名 | 备注 | 说明 |
|---|---|---|
| audio | 音频 | 指纹计算重要指标 |
| canvas | 浏览器画布元素 | 指纹计算重要指标 |
| fonts | 浏览器字体 | - |
| hardware | 浏览器能获取的硬件信息 | 由于安全问题,浏览器获取的硬件信息不多。利用 navigator.deviceMemory、WebGL 特性,如:Renderer: WebKit WebGL, Vendor: WebKit, Version: WebGL 1.0 (OpenGL ES 2.0 Chromium) |
| locales | 浏览器语言、时区信息 | navigator.language:语言;Intl:国际化 |
| math | 数学常数属性和数学函数 | 操作系统架构不同,浮点运算的结果不同 |
| permissions | 浏览器权限 | 只计算权限开关,不计算权限请求结果 |
| plugins | 浏览器插件 | navigator.plugins |
| screen | 屏幕信息 | - |
| system | 浏览器信息 | browser:浏览器对象;navigator.platform:浏览器所在的平台;navigator.cookieEnabled:cookie开关;navigator.userAgent:ua信息;navigator.hardwareConcurrency:操作系统内核数;ApplePaySession.supportsVersion:Apple Pay(是否支持Apple Pay) |
| webgl | 2D/3D 图形 API | 指纹计算重要指标。通过在 WebGL 上渲染 3D 图形并分析其渲染结果差异,差异可能来自于图形驱动程序、硬件特性、操作系统、浏览器版本 |
fingerprintjs
| 参数名 | 备注 |
|---|---|
| apple_pay | |
| architecture | 区分系统架构,x86/x86-64 |
| audio_base_latency | 音频兼容。Chrome和Firefox中会有警告,禁用 |
| audio | |
| canvas | |
| color_depth | window.screen.colorDepth |
| color_gamut | matchMedia |
| contrast | matchMedia |
| cookies_enabled | |
| cpu_class | navigator.cpuClass 是一个非标准的、过时的属性,用于返回用户计算机的 CPU 等级。 |
| device_memory | navigator.deviceMemory |
| dom_blockers | |
| font_preferences | |
| fonts | |
| forced_colors | |
| hardware_concurrency | (CPU 内核)数量 |
| hdr | matchMedia((dynamic-range: ${value})) |
| indexed_db | !!window.indexedDB |
| inverted_colors | |
| languages | navigator.languages |
| local_storage | |
| math | |
| monochrome | |
| open_database | |
| os_cpu | 系统的 CPU 信息,火狐可用 |
| pdf_viewer_enabled | navigator.pdfViewerEnabled 浏览器是否支持内置的 PDF 查看器 |
| platform | Chrome、iPad' : 'iPhone |
| plugins | |
| private_click_measurement | |
| reduced_motion | |
| reduced_transparency | |
| screen_frame | |
| screen_resolution | |
| session_storage | |
| timezone | 时区、夏令时 |
| touch_support | |
| vendor_flavors | 不同浏览器内核 |
| vendor | navigator.vendor |
| webgl |
设备判断与风险
- 初步想法是通过浏览器指纹+账户+ip地址+短信验证+交易密码作为主要判断逻辑。
- ip地址风险检测:以省或市为维度,变化则可疑。
交易密码风险检测:
- 错误次数,比如输入错3次则锁定账号,下次交易必须扫脸,交易密码用户可配置开关。
- 密码输入习惯,比如输入速度、输入值与常用密码匹配程度等判断是否有风险。
结论:
- 搭配登录账号和ip地址判断,浏览器指纹重复对业务影响不大(因为就算浏览器指纹重复,用户账号和ip地址大概率不同)。
- 手机丢失或者验证码窃取的情况,风险存在,如果要规避,可以考虑以交易或审核额度为阈值,考虑是否执行扫脸、人工验证或短信场景限额。
- 业务不能过度依赖浏览器指纹指作为交易安全相关的判断逻辑。
补充
1、参考 Fingerprint Pro、creepjs,可以增加后端服务,辅助指纹计算或者反欺诈。
2、指纹库采集数据参考
json
{
"audio": {
"sampleHash": 1168.9068228197468,
"oscillator": "sine",
"maxChannels": 1,
"channelCountMode": "max"
},
"canvas": {
"commonImageDataHash": "aaedcbe9cfef7921f773da32c513249c"
},
"fonts": {
"Arial": 448.03125,
"Arial Black": 531.9140625,
"Arial Narrow": 367.3828125,
"Calibri": 420.046875,
"Candara": 435.4453125,
"Century": 484.03125,
"Century Gothic": 474.36328125,
"Comic Sans MS": 462.4453125,
"Constantia": 469.86328125,
"Courier": 432.0703125,
"Courier New": 432.0703125,
"Franklin Gothic Medium": 431.82421875,
"Garamond": 428.203125,
"Georgia": 475.2421875,
"Helvetica": 448.03125,
"Impact": 395.54296875,
"Lucida Bright": 481.81640625,
"Lucida Console": 433.828125,
"Lucida Sans Unicode": 472.0078125,
"Segoe Print": 514.30078125,
"Segoe Script": 525.234375,
"Segoe UI": 450,
"Tahoma": 432.45703125,
"Times": 447.9609375,
"Times New Roman": 447.9609375,
"Trebuchet MS": 428.90625,
"Verdana": 486.5625
},
"hardware": {
"videocard": {
"vendor": "WebKit",
"vendorUnmasked": "Google Inc. (Intel)",
"renderer": "WebKit WebGL",
"rendererUnmasked": "ANGLE (Intel, Intel(R) Iris(R) Xe Graphics (0x00009A49) Direct3D11 vs_5_0 ps_5_0, D3D11)",
"version": "WebGL 1.0 (OpenGL ES 2.0 Chromium)",
"shadingLanguageVersion": "WebGL GLSL ES 1.0 (OpenGL ES GLSL ES 1.0 Chromium)"
},
"architecture": 255,
"deviceMemory": "8",
"jsHeapSizeLimit": 3760000000
},
"locales": {
"languages": "zh-CN",
"timezone": "Asia/Shanghai"
},
"permissions": {
"accelerometer": "granted",
"background-fetch": "granted",
"background-sync": "granted",
"camera": "prompt",
"clipboard-read": "prompt",
"clipboard-write": "granted",
"display-capture": "prompt",
"gyroscope": "granted",
"geolocation": "prompt",
"local-fonts": "prompt",
"magnetometer": "granted",
"microphone": "prompt",
"midi": "prompt",
"notifications": "prompt",
"payment-handler": "granted",
"persistent-storage": "prompt",
"storage-access": "granted",
"window-management": "prompt"
},
"plugins": {
"plugins": [
"PDF Viewer|internal-pdf-viewer|Portable Document Format",
"Chrome PDF Viewer|internal-pdf-viewer|Portable Document Format",
"Chromium PDF Viewer|internal-pdf-viewer|Portable Document Format",
"Microsoft Edge PDF Viewer|internal-pdf-viewer|Portable Document Format",
"WebKit built-in PDF|internal-pdf-viewer|Portable Document Format"
]
},
"screen": {
"is_touchscreen": false,
"maxTouchPoints": 0,
"colorDepth": 24,
"mediaMatches": [
"prefers-contrast: no-preference",
"any-hover: hover",
"any-pointer: fine",
"pointer: fine",
"hover: hover",
"update: fast",
"prefers-reduced-motion: no-preference",
"prefers-reduced-transparency: no-preference",
"scripting: enabled",
"forced-colors: none"
]
},
"system": {
"platform": "Win32",
"cookieEnabled": true,
"productSub": "20030107",
"product": "Gecko",
"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36",
"hardwareConcurrency": 8,
"browser": {
"name": "Chrome",
"version": "130.0"
},
"applePayVersion": 0
},
"webgl": {
"commonImageHash": "0d8f992a226633fedc65776882713958"
},
"math": {
"acos": 1.0471975511965979,
"asin": -9.614302481290016e-17,
"atan": 4.578239276804769e-17,
"cos": -4.854249971455313e-16,
"cosh": 1.9468519159297506,
"e": 2.718281828459045,
"largeCos": 0.7639704044417283,
"largeSin": -0.6452512852657808,
"largeTan": -0.8446024630198843,
"log": 6.907755278982137,
"pi": 3.141592653589793,
"sin": -1.9461946644816207e-16,
"sinh": -0.6288121810679035,
"sqrt": 1.4142135623730951,
"tan": 6.980860926542689e-14,
"tanh": -0.39008295789884684
}
}