3. 设备端指纹采集:IMEI/IDFA/AAID、MAC地址、IP地址、User-Agent、屏幕分辨率与DPI
设备指纹的采集,说白了就是给每个设备拍一张「身份证照片」。这张照片拍得好不好,直接决定了后续风控模型能不能认准人。我做了这么多年安全,见过太多因为采集不全或者采集错误导致误杀、漏杀的案例。
今天咱们就把这些核心采集项一个一个拆开看。每个字段怎么拿、有什么坑、在Android和iOS上有什么区别,我都会结合项目经验讲清楚。
3.1 设备标识符:IMEI / IDFA / AAID
设备标识符是指纹里最核心的部分。但不同系统、不同版本,获取方式天差地别。
3.1.1 IMEI(国际移动设备识别码)
IMEI是GSM网络的设备唯一编号,相当于手机的「身份证号」。在Android 10之前,获取IMEI相对容易,但之后权限收紧得非常厉害。
我曾经在一个金融项目中,客户坚持要采集IMEI做风控。结果上线后发现Android 10以上设备全部采集失败,导致大量用户被判定为「新设备」触发二次验证。后来我们改用了AAID + 设备特征组合的方案,才解决了这个问题。
iOS上IMEI从iOS 5开始就被完全屏蔽了,开发者根本拿不到。所以如果你做跨平台方案,千万别把IMEI当成必选项。
3.1.2 IDFA(广告标识符)
IDFA是iOS上的广告追踪标识符。用户可以在设置里「限制广告追踪」或者「重置IDFA」,所以它不是一个稳定的标识。
iOS 14之后,获取IDFA需要弹出App Tracking Transparency(ATT)弹窗,用户拒绝就返回全零。我见过一个电商App,因为没处理好ATT授权,导致70%的iOS用户IDFA为空,风控模型直接崩了。
3.1.3 AAID(Android广告标识符)
AAID是Google Play服务提供的广告标识,Android设备基本都支持。用户可以重置,但不会像IDFA那样频繁变化。
获取AAID需要Google Play服务,国内很多定制ROM可能没有。我遇到过某国产手机厂商把Google Play服务阉割了,AAID返回空。这种情况下,我们只能退回到用设备特征组合生成指纹。
| 标识符 | 平台 | 稳定性 | 获取难度 | 备注 |
|---|---|---|---|---|
| IMEI | Android | 高 | 高(Android 10+受限) | 合规风险大,建议放弃 |
| IDFA | iOS | 中(可重置) | 中(需ATT授权) | 用户拒绝后为空 |
| AAID | Android | 中(可重置) | 低 | 依赖Google Play服务 |
3.2 网络层指纹:MAC地址与IP地址
网络层的两个字段,看似简单,实则暗坑无数。
3.2.1 MAC地址
MAC地址是网卡的物理地址,理论上全球唯一。但现实很骨感。
Android 6.0之后,系统API返回的是随机MAC地址(私有MAC)。Android 10之后,非系统应用根本拿不到真实MAC。iOS从iOS 7开始就返回02:00:00:00:00:00这种固定值。
我记得有个做WiFi探针的公司,想通过采集手机MAC来识别用户。结果发现Android 10以上的设备,每次扫描返回的MAC都不一样。他们以为是设备坏了,查了半天才发现是系统行为。
3.2.2 IP地址
IP地址变化太频繁了。用户从WiFi切到4G,IP就变了。甚至同一个WiFi下,DHCP租约到期也可能变。
但IP地址在风控里依然有用——不是用来标识设备,而是用来做地理位置校验和代理检测。比如一个设备指纹声称在北京,但IP显示在洛杉矶,那大概率是代理。
我处理过一个刷单案例:攻击者用同一台设备,通过切换代理IP来模拟不同地区的用户。我们通过IP的ASN(自治系统号)和时区信息,发现这些IP都来自同一个数据中心,直接判定为异常。
3.3 应用层指纹:User-Agent
User-Agent(UA)是浏览器或App在HTTP请求中携带的标识字符串。它包含操作系统、浏览器版本、设备型号等信息。
UA的格式在不同平台上差异很大。Web端最复杂,移动端相对统一。但UA是可以伪造的,很多爬虫工具都会修改UA。
我建议把UA当成一个辅助信号,而不是主要指纹。你可以从UA里提取出操作系统版本、浏览器内核、设备型号等结构化信息,然后跟其他字段做交叉验证。
// 一个典型的移动端UA
Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)
AppleWebKit/605.1.15 (KHTML, like Gecko)
Version/16.0 Mobile/15E148 Safari/604.1
// 提取关键信息
OS: iOS 16.0
Browser: Safari 16.0
Device: iPhone
Engine: WebKit 605.1.15
3.4 硬件特征:屏幕分辨率与DPI
屏幕分辨率和DPI是硬件指纹里比较稳定的字段。用户不会频繁换屏幕,而且不同型号的设备,这两个值的组合通常是唯一的。
但这里有个坑:分辨率受系统UI缩放影响。比如iPhone 14 Pro Max的实际分辨率是2796x1290,但系统UI缩放后,逻辑分辨率可能是430x932。你采集的时候要区分是物理分辨率还是逻辑分辨率。
DPI(每英寸像素数)也是一个重要指标。两个设备可能有相同的分辨率,但屏幕尺寸不同,DPI就不同。比如5.5寸的1080P和6.5寸的1080P,DPI差了将近20%。
| 设备 | 物理分辨率 | 逻辑分辨率 | DPI | 屏幕尺寸 |
|---|---|---|---|---|
| iPhone 14 Pro Max | 2796x1290 | 430x932 | 460 | 6.7寸 |
| Samsung S23 Ultra | 3088x1440 | 412x915 | 500 | 6.8寸 |
| Xiaomi 13 Pro | 3200x1440 | 360x780 | 522 | 6.73寸 |
你看,这三个设备的物理分辨率都不一样,DPI也不同。组合起来就是一个很强的指纹特征。
3.5 指纹采集的整体架构
说了这么多单个字段,咱们来看看它们怎么组合成一个完整的指纹采集流程。
这个架构图展示了完整的采集流程。从SDK入口开始,分三条线采集设备标识符、网络层和硬件特征。采集到的原始数据经过清洗和标准化,最后生成唯一的设备指纹。
嗯,这里要注意:每个字段的采集都要做异常处理。比如获取AAID时Google Play服务不可用,要能优雅降级到备用方案。我见过一个App,因为AAID获取失败直接崩溃,用户反馈差到爆。
3.6 采集策略总结
最后总结一下我的个人经验:
- 优先使用AAID和IDFA,但要做好用户重置和授权拒绝的预案
- IMEI能不用就不用,合规风险太大,而且Android 10以上基本拿不到
- MAC地址已经废了,别在上面浪费时间
- IP地址用来做辅助校验,别用来做唯一标识
- 屏幕分辨率和DPI是稳定信号,但要注意区分物理和逻辑分辨率
- 所有字段都要做异常处理,采集失败不能影响用户体验
你想想看,如果这些字段都采集对了,组合起来的指纹稳定性会非常高。我做过一个测试,在100万台设备上,仅用分辨率+DPI+AAID+UA这四个字段,就能区分出99.7%的设备。剩下的0.3%是同一型号、同一批次、同一网络环境的设备,这种场景下需要引入更多行为特征才能区分。