一、结论速览(TL;DR)
按"作用域"把方案分成四层,直接对号入座:
| 作用域 | 含义 | 推荐 ID(零/低权限) | 平台 |
|---|---|---|---|
| 仅本 App | 只有当前 App 可见,跨 App 不通 | 自生成 UUIDv4 存 Keychain / Keystore;Firebase FID | iOS / Android |
| 同开发商 | 同一开发者/同一签名的一批 App 之间共享 | iOS:IDFV + Keychain Access Group Android:App Set ID / ANDROID_ID(SSAID) |
iOS / Android |
| 整机(设备级) | 同一设备上所有 App 都能拿到同一个值 | OAID(中国厂商 MSA 体系,零权限);GAID / IDFA(需授权或声明权限) | Android 为主 |
| 全局(跨开发商) | 理论上所有 App 共享同一物理设备 ID | ❌ 无合规零权限方案;只剩设备指纹(被明令禁止)或用户账号登录 | 全平台 |
① iOS
IDFV 或 Keychain Access Group 共享的自生成 UUID;② Android App Set ID(同 Play 开发者账号)或 ANDROID_ID(同签名)。再叠加 ③ 服务端 ID 合并映射表做兜底。
大厂设备 ID 体系总表(第九 / 十七 / 十八节结论合并 · 一眼扫完)
把第十七、十八两节的横向对比合并成一张表,并补入第十二节的腾讯 QIMEI。八家全部收敛到同一套范式,差别只在"是否对外开放"与"采集激进度":
| 公司 | 设备级 ID | 跨客户端能力 | 是否对外开放 | 一句话定位 | 来源 |
|---|---|---|---|---|---|
| 字节 / 火山引擎 | device_id(ssid / BDID 衍生) | ✅ 官方明文:同设备不同 App 相同 device_id(服务端设备注册服务保证) | ✅ 对外(DataFinder / 增长营销套件 / 穿山甲) | 证据等级最高,可直接作架构对标 | 🔗[103][104] |
| 阿里 | UTDID → DeviceID;设备指纹 DeviceToken | ✅ UTDID 经系统公共存储组件在阿里系 App 间共享 | ✅ 阿里云设备风险识别 / 设备风控服务对外售卖 | 与字节同路线,且做了字段合规分级 | 🔗[42][130] |
| 腾讯(QIMEI) | QIMEI / QIMEI36(服务端合成 + ID 找回) | ✅ 服务端 ID 关系库 + 找回算法实时下发终端唯一 ID | 部分(灯塔 / 腾讯开放平台,需注册审核) | 本报告推荐架构的"工业级实现" | 🔗[30][31] |
| 京东 | okuuid UUID / 设备指纹 ID | ✅ okuuid-jdmall「与主站打通、UUID 保持一致」;20+ App 实践 | 部分(京东云设备指纹对外售卖) | 提供"与主站打通"的产品化开关 | 🔗[105][108] |
| 网易 | 易盾 DNA 指纹 Sid / 基础 SDK Device ID | ✅ 服务端版跨 H5 / 小程序提升唯一性;集团基础 SDK 统一 Device ID | 部分(易盾对外售卖) | DNA 指纹 + 智能追回(官方披露找回率 8.9%) | 🔗[110][114] |
| 美团 | xid / dfpid(mtguard) | ✅ 同签名 AndroidID 共享 + unionid 跨 App 归一(逆向佐证) | ❌(内部风控 / 账号安全为主) | native 库 + 跨 App unionid 归一 | 🔗[117][119][120] |
| 快手 | did(短视频侧)/ EGID(设备注册服务) | ~ 设备注册服务下发 EGID(逆向佐证);隐私政策列多标识采集 | ❌(隐私政策 + 联运 SDK 采集为主) | 偏内容 / 广告 / 联运用途 | 🔗[127][128][129] |
| 拼多多 | anti_content / anti-token(非独立设备 ID) | ~ 捆在风控签名内,不暴露设备 ID | ❌ | 最"闭":强风控 + OLLVM 混淆,不宜照搬 | 🔗[134][135] |
二、问题本质:为什么"跨 App 唯一"这么难
2.1 操作系统沙箱是根源
iOS 和 Android 的 App 运行在独立沙箱里,默认互相看不到对方的数据。字符串 UUID() 每次调用都生成全新的值,且 App 卸载即丢失,除非你主动把它存到"跨卸载存活"的地方(Keychain / 硬件)。🔗 [19]
2.2 "唯一标识"其实有三个正交的维度
业界把标识符按三个维度切分,理解这三个维度,后面所有方案的取舍就一目了然(🔗 [7][21]):
维度一:作用域 Scope
- 应用级:仅本 App
- 开发者/套件级:同一开发商的一批 App
- 设备级:整机所有 App
- 全局级:跨开发商(现代 OS 已基本废弃)
维度二:可重置性 Resettable
- 会话级(每次启动变)
- 安装级(卸载即变)
- 出厂重置级(恢复出厂才变)
- 永久级(恢复出厂也不变,如 IMEI)
维度三:存活期 Persistence(是否跨卸载/跨备份存活)。
三、权限常识:别把"权限"和"声明"混为一谈
用户最关心的"不要太多权限",这里先澄清几个层次(很多方案其实一个运行时权限都不要):
| 层次 | 说明 | 典型例子 |
|---|---|---|
| 运行时权限(弹窗、用户可拒) | 最"重"的权限,安装后需用户点"允许" | READ_PHONE_STATE(读 IMEI)、ATT 追踪授权 |
| 普通权限(清单声明即授予) | 无需弹窗,但会在隐私扫描/应用商店里被标记 | AD_ID(Android 13+ 用广告 ID 必须声明) |
| 能力声明 / Entitlement | Xcode 里配置,发布时生效,无用户弹窗 | iOS Keychain Access Group |
| 零权限(推荐) | 什么都不用声明,直接调用 API | ANDROID_ID、App Set ID、IDFV、OAID、MediaDrm、Keychain |
四、标识符全景对比(Android + iOS)
这张表是本次调研的核心成果,把所有主流标识符按统一维度拉平对比:
| 标识符 | 平台 | 作用域 | 跨 App 共享? | 权限 | 重置 / 失效条件 | 持久性 | 来源 |
|---|---|---|---|---|---|---|---|
| ANDROID_ID (SSAID) | Android | 签名 × 用户 × 设备 | ✅ 同签名 App 共享 | 零权限 | 恢复出厂、切换用户、换签名证书 | 跨重装存活(Android 8+) | 🔗[3][11][12] |
| App Set ID | Android | Google Play 开发者账号 | ✅ 同 Play 账号 App 共享(即使签名不同) | 零权限 | 恢复出厂 / 该套 App 全卸载 / 13 个月无访问 | 跨重装存活 | 🔗[4][5] |
| GAID / AAID 广告 ID | Android | 整机(设备级) | ✅ 所有 App 共享 | 普通权限 AD_ID | 用户可随时重置/删除;未声明权限则返回全 0 | 可重置,不稳定 | 🔗[8][9][16] |
| OAID 匿名设备标识 | Android(国内) | 整机(设备级) | ✅ 所有 App 共享 | 零权限 | 恢复出厂重置;用户可关闭关联 | 跨重装存活 | 🔗[13][14][15] |
| VAID 开发者匿名标识 | Android(国内) | 设备 + 开发者 | ✅ 同开发者 App 共享 | 零权限 | 重装 App 重置;未读取过则不重置 | 中等 | 🔗[13][15] |
| AAID 应用匿名标识 | Android(国内) | 应用沙箱(仅单个 App) | ❌ 每个 App 不同 | 零权限 | 重装 / 清除数据重置 | 低 | 🔗[13] |
| MediaDrm (Widevine deviceUniqueId) | Android | 整机(硬件级) | ✅ 所有 App 共享 | 零权限 | 多数设备恢复出厂也存活;部分机型/模拟器不支持 | 极高(近乎硬件永久) | 🔗[10][20] |
| IMEI / MEID | Android | 整机(硬件永久) | ✅ | 已废弃 | 永久;但 Android 10+ 普通应用拿不到(需系统级权限) | —(不可用) | 🔗[7][14] |
| MAC 地址 | 双端 | 整机 | ✅ | 已废弃 | Android 6+ 随机化;iOS 7+ 固定假值 02:00:00… | —(不可用) | 🔗[3] |
| IDFV identifierForVendor | iOS | 同一开发商(vendor) | ✅ 同 vendor App 共享 | 零权限 | 该 vendor 所有 App 被卸载后重装即变 | 跨重装存活(只要还有同 vendor App 在) | 🔗[1][17] |
| IDFA advertisingIdentifier | iOS | 整机(设备级) | ✅ | ATT 授权 | 用户可重置/关闭;拒绝授权则返回全 0 | 可重置 | 🔗[17][18] |
| Keychain UUID 自生成 + Keychain | iOS | 可配置(App 或共享组) | ✅ 同 Team 共享组 | 零权限(需配置 Entitlement) | 刷机/抹除重置;通常跨卸载存活 | 高(跨重装) | 🔗[1][19][24] |
| DeviceCheck | iOS | 整机(按开发者) | ✅ 同 Team App 可读 | 零权限 | 跨重装/跨刷机存活;仅 2 bit 状态位 | 极高 | 🔗[2][3] |
| Firebase FID | 双端 | 单个 App 安装实例 | ❌ 每 App 独立 | 零权限 | 重装 / 清数据 / 270 天不活跃 | 低(安装级) | 🔗[22][23] |
| 设备指纹 fingerprinting | 双端 | 整机(跨开发商) | ✅(概率拼接) | 违规 | 不保证命中率,且有合规风险 | —(不推荐) | 🔗[26][21] |
若「要跨不同开发商的 App」→ 国内用 OAID,海外只能 GAID/IDFA(含权限代价)或账号。
五、Android 方案逐个详解
5.1 ANDROID_ID(SSAID)—— 同签名 App 的零权限首选
从 Android 8.0 (API 26) 起,ANDROID_ID 的取值由三元组决定:App 签名证书 + 系统用户 + 设备。🔗[3][12]
- ✅ 同一签名证书的多个 App(同一开发商),在同一设备同一用户下拿到同一个 ANDROID_ID。
- ❌ 不同签名的 App(哪怕同一开发者账号)会拿到不同的值 —— 这是它与 App Set ID 的关键区别。
- ✅ 跨 App 重装存活(8.0+),恢复出厂或切换系统用户会变。
- ✅ 不需要任何权限。
// Kotlin —— 零权限读取
import android.provider.Settings
val androidId = Settings.Secure.getString(
context.contentResolver, Settings.Secure.ANDROID_ID
)
// 再用你自己的密钥做 SHA-256 哈希后上报,避免明文设备标识外泄
5.2 App Set ID —— 跨签名的"同 Play 账号"方案(重点推荐)
Google Play 服务提供的 app set ID,专为"同一组织的一批 App 之间关联行为(分析、反作弊、频次控制)"而设计。🔗[4][5]
- 🔑 由 Google Play 商店安装的 App,返回的 ID scope = 同一 Google Play 开发者账号下的所有 App —— 即使这些 App 签名证书不同,也共享同一个 App Set ID。🔗[4]
- ✅ 零权限(普通 manifest 权限都不需要),是 GAID 之外最"干净"的跨 App 方案。🔗[16]
- ⚠️ 重置条件:恢复出厂 / 该套 App 全部被卸载 / 超过 13 个月无任何 App 访问。因此不要缓存后长期使用,每次用时实时取。🔗[4]
- ⚠️ 非 Google Play 安装(第三方商店/侧载)或设备无 Google 服务时,会退化成 scope = 单个 App。这对国内 Android 生态是硬伤 → 国内要搭配 OAID 使用。
// Kotlin
val client = AppSet.getClient(applicationContext) as AppSetIdClient
client.appSetIdInfo.addOnSuccessListener { info ->
val scope = info.scope // SCOPE_APP=1 或 SCOPE_DEVELOPER=2
val id = info.id // UUID v4 格式
}
🔗 官方 API 参考:AppSetId(作用域常量 SCOPE_APP / SCOPE_DEVELOPER)[5]。
5.3 GAID / 广告 ID —— 设备级,但有权限与用户可重置
- ✅ 设备级、所有 App 共享,是海外广告归因的标准 ID。
- ⚠️ Android 13+ 必须在 manifest 声明
com.google.android.gms.permission.AD_ID,否则返回全 0。🔗[8][9] - ⚠️ 用户"删除广告 ID / 退出个性化"后,系统返回
00000000-0000-0000-0000-000000000000(全零)。🔗[8] - ⚠️ 不得把重置前后的 GAID 拼接关联(合规红线)。🔗[9][16]
- 📌 未来:Google 曾推 Privacy Sandbox 想取代 GAID,但 2025 年 10 月已正式退役该套 API,广告 ID 继续存活。🔗[16][25]
5.4 OAID(中国 MSA 补充设备标识体系)—— 跨开发商零权限的唯一解
由于 Android 10 起 IMEI/MAC 对普通应用彻底关闭,工信部下属机构联合华为、小米、OPPO、vivo、三星、魅族等厂商,制定了《移动智能终端补充设备标识体系》,通过统一的 MSA SDK 读取。🔗[13][14]
体系包含四类标识(四者之间不存在映射关系):🔗[13][15]
| 简称 | 全称 | 作用域 | 跨 App | 重置性 |
|---|---|---|---|---|
| UDID | 设备唯一标识符 | 硬件永久 | ✅ | 不可重置 |
| OAID | 开放匿名设备标识符 | 设备级 | ✅ 所有 App 共享 | 恢复出厂重置 |
| VAID | 开发者匿名设备标识符 | 设备 + 开发者 | ✅ 同开发者共享 | 重装重置 |
| AAID | 应用匿名设备标识符 | 单 App 沙箱 | ❌ 每 App 不同 | 重装/清数据重置 |
5.5 MediaDrm / Widevine deviceUniqueId —— 硬件级、零权限,但非官方推荐
通过 Widevine DRM 的 PROPERTY_DEVICE_UNIQUE_ID 可拿到一个设备唯一、无需权限、多数情况恢复出厂也存活的硬件级 ID。🔗[10][20]
// Kotlin —— SHA-256 后使用
val WIDEVINE_UUID = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L)
val drm = MediaDrm(WIDEVINE_UUID)
val raw = drm.getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID)
val id = MessageDigest.getInstance("SHA-256").digest(raw).joinToString(""){"%02x".format(it)}
deviceUniqueId,被部分厂商逐步弱化;④ Google 官方最佳实践并不推荐用它做通用设备标识。建议仅作兜底而非主力。🔗[10][20][7]
5.6 已废弃:IMEI / MAC / 序列号
- IMEI:Android 10 (API 29) 起,普通应用获取会抛
SecurityException或返回 null,只有系统应用/设备管理员拿到READ_PRIVILEGED_PHONE_STATE才可用。🔗[7][14] - MAC:Android 6+ 对非本机 MAC 随机化;iOS 7+ 固定返回
02:00:00:00:00:00。🔗[3]
🔗 Google 官方《唯一标识符最佳做法》明确建议:能用可重置标识符就别用硬件 ID;绝大多数非广告场景用 Firebase 安装 ID (FID) 或本应用自生成 GUID。[7]
六、iOS 方案逐个详解
6.1 IDFV(identifierForVendor)—— iOS 上"同开发商跨 App"的零权限首选
Apple 官方定义:同一 vendor(开发商)在同一设备上的所有 App 共享同一个 IDFV;不同 vendor 的 App、不同设备取值不同。🔗[1]
- vendor 由 App Store 提供的数据决定;非商店安装(企业/开发版)则按 Bundle ID 反域名前缀计算(
com.example.app1与com.example.app2同 vendor)。🔗[1] - ✅ 无需任何权限、无需 ATT 授权。🔗[1][17]
- ⚠️ 重置条件:当用户删除该 vendor 的所有 App 后再重装,IDFV 会变。所以只有单一 App 的开发商,IDFV 等于安装级,重装即变。🔗[1][19]
- 📌 Apple 明确允许:IDFV 可用于"同一内容提供者的跨 App 分析",不需要 ATT;但不得与其他数据结合追踪跨公司行为。🔗[18]
// Swift
if let idfv = UIDevice.current.identifierForVendor?.uuidString {
// 注意:重启后未解锁前可能为 nil,需容错重试
}
6.2 Keychain Access Group —— 跨 App 共享"自生成 UUID"的官方机制
这是实现"跨 App 完全一致的 UUID"最可控的方案:在首个 App 首次运行时生成一个 UUIDv4,写入 Keychain;同签名组(同 Apple Team ID)的其它 App 通过 共享 Access Group 读到同一个值。🔗[19][24]
- ✅ 跨卸载重装存活(Keychain 不随 App 删除而清除,历史上 iOS 10.3 Beta 曾试图清除,后撤销)。🔗[17][19]
- ✅ 零权限,仅需在 Xcode 配置
keychain-access-groupsentitlement(格式必须带 Team ID 前缀:TEAMID.com.example.shared)。🔗[24] - ⚠️ 仅限同一开发团队:不同 Team 的 App 无法通过 Access Group 共享(Team ID 前缀强制隔离)。🔗[24]
- ⚠️ App 在开发者账号间转移后,旧 Team ID 下的 Keychain 项将不可读,需要迁移方案。🔗[24]
// entitlements:keychain-access-groups = $(AppIdentifierPrefix)com.example.shared
let teamID = "SKMME9E2Y8" // 你的 Team ID
let group = "\(teamID).com.example.shared"
// 所有同 Team App 用同一 kSecAttrAccessGroup 读写同一 key → 得到同一个 UUID
6.3 IDFA —— 设备级,但需要 ATT 授权
- iOS 14.5+ 必须通过 App Tracking Transparency 弹窗拿到用户授权,否则返回全 0。🔗[17][18]
- 用户可在设置中关闭"允许 App 请求跟踪",或"限制广告跟踪"→ 全 0。🔗[18]
- Info.plist 需
NSUserTrackingUsageDescription。🔗[18]
6.4 DeviceCheck —— 隐私友好的"设备级状态位"(跨刷机存活)
- 用
DCDevice生成一个临时 token 交给你自己的服务器,服务端向 Apple 查询/写入该设备的 2 个二进制位。🔗[2] - ✅ 零权限;跨 App 重装、跨设备重置存活(数据存在 Apple 服务器)。🔗[3]
- ⚠️ 只能存 2 bit(4 种状态),不是通用 UUID,适合"防薅羊毛/标记异常设备",不能当主键。🔗[2]
6.5 已废弃:UDID
硬件永久 UDID 自 2012 年宣布弃用、2013 年起 App Store 拒绝访问,是现代隐私标识体系的起点。🔗[17][18]
七、开源 / 商用 SDK 是怎么做的(可直接抄作业)
Flutter: device_id_manager
- iOS:Keychain 里存 UUIDv4,跨重装存活;
- Android:
MediaDrm 硬件 ID+ 包名 → SHA-256 → 每 App 一个 ID;MediaDrm 不可用时退回 UUIDv4; - 零权限,跨重装存活。
🔗 pub.dev/packages/device_id_manager [20]
Ping Identity: 设备标识 SDK
- iOS 默认:Keychain 里的 RSA 密钥对 → SHA-256 公钥 → 标识;跨 App 共享需 Keychain Access Group;
- Android 默认:KeyStore 生成密钥对(重装即变);要跨 App 需切到
AndroidIDDeviceIdentifier(ANDROID_ID,API 26+)。
🔗 developer.pingidentity.com [11]
shieldlabs 持久化设备 ID 范式
- 推荐"本地生成 + 加密存储(EncryptedSharedPreferences / Keychain)";
- 强调迁移顺序:先查旧存储再生成新 ID,否则会产生重复身份。
🔗 shieldlabs.ai [19]
八、头部厂商实践(实证)
8.1 MMP 归因厂商(海外)
AppsFlyer / Adjust / Branch 等移动归因平台的 SDK 对多 ID 的支持与限制:🔗[17][18][27]
- iOS:优先 IDFA(需用户同意),IDFA 缺失时退回 IDFV(用于同一开发商跨 App 归因与测试设备注册)。🔗[17]
- Android:优先 GAID;第三方商店场景用 OAID;国内场景可配置采集 IMEI / Android ID。🔗[18][27]
- 明确区分了 IDFV(同 vendor 共享)与 GAID/IDFA(设备级、可重置)的用途边界。🔗[27]
8.2 国内游戏 SDK 隐私清单(实证:他们实际收什么)
查阅灵犀、祖龙、网易等多家游戏公司的第三方 SDK 共享清单可见,国内同一款游戏往往同时采集一串标识符,而非单一 ID:🔗[28][29]
| SDK 类型 | 常见采集的标识符 |
|---|---|
| 设备标识 SDK(阿里/华为等) | OAID、Android ID、设备信息 |
| 统计 SDK(友盟/网易) | IMEI、OAID、GAID、Android ID、设备序列号 |
| 游戏联运 SDK(华为/OPPO/vivo/小米) | IMEI、Android ID、OAID/VAID/AAID、MAC |
| iOS 侧 | IDFV、IDFA |
| 豌豆/九游等渠道 | 设备标识信息(唯一设备识别码)、OAID |
⚠ 注意:设备指纹类做法虽普遍存在,但学术界已实测发现大量 App 通过第三方 SDK 做跨 App 指纹追踪(游戏/漫画/交友类 App 覆盖率最高),这类行为在合规趋严下风险上升。🔗[26]
九、推荐架构:分层 ID + 服务端合并映射
基于以上调研,给出可直接落地的方案。核心思想是不要把唯一性押在单一标识符上,而是:本地主键(稳定)+ 平台锚点(跨 App)+ 服务端合并(兜底)。
9.1 三层结构
| 层 | 作用 | 实现 | 说明 |
|---|---|---|---|
| L1 本地主键 | SDK 自己持有的稳定 UUID | 首启生成 UUIDv4 → iOS 存 Keychain;Android 存 EncryptedSharedPreferences(Keystore) 或私有文件 | 跨卸载存活;是所有上报的"事实主键" |
| L2 跨 App 锚点 | 让不同 App 的 L1 能对上号 | iOS:IDFV / Keychain Access Group;Android:App Set ID → ANDROID_ID → OAID | 零权限优先,作为"设备锚点"随 L1 一起上报 |
| L3 服务端合并 | 把多源 ID 归并到一个全局 UUID | ID 映射表:设备锚点 ↔ 全局 UUID;冲突就近合并,带置信度 | 处理重置/换机/多路径上报 |
9.2 Android 上报优先级(零权限链路)
优先级(取第一个非空且有效):
[1] OAID —— 设备级、跨开发商、零权限(国内厂商 MSA SDK)
[2] App Set ID —— 同 Play 开发者账号、零权限(海外 Google Play 场景)
[3] ANDROID_ID —— 同签名 App 共享、零权限(三方商店/无 GMS 场景)
[4] MediaDrm ID —— 硬件级兜底、零权限(应作为最后手段,先做兼容性探测)
[5] Firebase FID / 本地 UUID —— 单 App 兜底
另:本地 UUID(L1) 始终随包上报,作为去重主键。
9.3 iOS 上报优先级(零权限链路)
优先级:
[1] Keychain 共享 UUID —— 同 Team 跨 App 完全一致(首选,需配 Access Group)
[2] IDFV —— 同 vendor 共享、零权限
[3] IDFA —— 设备级,但需 ATT 授权(有则用,无则跳过)
[4] DeviceCheck token —— 服务端可换取 2bit 设备状态(防刷兜底,非主键)
[5] 本地 UUID —— 始终随包上报
9.4 服务端合并伪代码
func resolveGlobalId(report):
# report 携带 { localUuid, idfv/oaid/appSetId/androidId, hash... }
candidates = [report.localUuid, report.appSetId or report.idfv, report.oaid or report.androidId]
# 1) 任一候选已映射到某个 globalUuid → 命中,直接复用
for c in candidates:
if g = idMap.get(c): return linkAndReturn(g, candidates)
# 2) 都没命中 → 新建一个全局 UUID,把所有候选写进映射表
g = newUuid()
for c in candidates:
if c: idMap.put(c, g) # 后续任一候选再次出现都能命中
return g
# 关键:置信度分层。OAID/AppSetID 比 ANDROID_ID 更能标识"设备",
# 冲突时以设备级锚点为准;本地 UUID 只保证"同一安装"连续。
- 重置爆炸:ANDROID_ID/AppSetID 会因恢复出厂/卸载套件而变 → 不要把它们当永久主键,只用"锚点",靠 L3 合并。
- 多值冲突:一台设备可能同时上报 OAID 和 Android ID,若两个锚点指向了不同的旧 globalUuid,需要定义合并规则(就近时间优先 / 设备级锚点优先)。
- 迁移顺序:升级 SDK 换存储格式时,先读旧存储再生成新 ID,顺序反了会产生"一个真实安装两个身份"。🔗[19]
十、合规红线(越界会被下架 / 罚款)
- 禁止设备指纹(fingerprinting):Google Play 与 Apple 均明确禁止用设备特征拼接来绕开用户对广告 ID 的选择;Apple 把"把 UUID 与设备信息组合成硬件指纹"列为违规。🔗[9][17][26]
- 不得拼接重置前后的广告 ID(GAID/IDFA reset 后重新关联)视为违反用户选择。🔗[9][16]
- ATT 未授权不得读取 IDFA(读到全 0 属正常,不得绕过)。🔗[18]
- 隐私清单:iOS 17 起需在
PrivacyInfo.xcprivacy声明标识符用途;Android 需在 Data safety 表单如实声明。🔗[19][9] - 国内:需在隐私政策中列明第三方 SDK 采集的标识符类型(本报告 8.2 的清单即为合规要求下的产物)。🔗[28][29]
⚠ 补充:欧盟曾对基于 IDFV 的广告使用开出罚单(CNIL 对 Voodoo 罚 300 万欧元),IDFV 用于广告跨 App 追踪在多法域有额外法律风险。🔗[16]
十一、决策树:你的场景该选哪个?
| 你的情况 | 推荐方案 | 权限代价 |
|---|---|---|
| 同公司多个 App,iOS + Android 都要跨 App 一致 | iOS:Keychain Access Group 共享 UUID(或 IDFV);Android:App Set ID + ANDROID_ID | 零权限 |
| SDK 装在不同开发商的 App 里,国内生态(华为/小米/OPPO/vivo…) | OAID(MSA 统一 SDK) + Android ID 兜底 | 零权限(需企业注册 + 年度证书) |
| 海外 Google Play 生态,跨 App 关联分析/反作弊 | App Set ID(+ GAID 用于广告) | 零权限 / GAID 需 AD_ID 声明 |
| 只要单 App 内稳定、跨重装 | iOS Keychain UUID / Android ANDROID_ID + 本地 UUID | 零权限 |
| 要"设备级、跨刷机、防薅羊毛" | Android MediaDrm(兜底探测);iOS DeviceCheck(2bit 状态) | 零权限,但能力有限 |
| 要真正全局唯一、跨任何 App 和设备 | ❌ 无合规方案 → 改用账号登录 + 服务端用户 ID | 需用户体系 |
十二、腾讯 QIMEI 专题(腾讯生态的"设备 ID 中台")
QIMEI 是上一版报告遗漏的重磅方案 —— 它是腾讯灯塔(Beacon)团队推出的终端设备 ID 精准识别体系,广泛用于腾讯系 App、腾讯游戏、广告归因与反作弊。它不属于"某一个系统标识符",而是一整套服务端合成 + ID 找回的中台能力,是本报告推荐架构的"工业级实现"。🔗[30]
12.1 QIMEI 的关键属性
| 维度 | 说明 | 来源 |
|---|---|---|
| 本质 | 不是系统 ID,而是腾讯服务端合成并下发的一个设备标识;客户端只负责采集与上报 | 🔗[30][34] |
| 形态 | 存在 QIMEI(旧,字段 A3) / QIMEI36(标准 36 位,字段 A153) / QIMEI16 多种形态;旧 QIMEI 可能来自 androidID/imei/mac 的计算结果 | 🔗[31][33] |
| 生成方式 | 服务端生成下发,并与 IMEI/MAC/IMSI/AndroidID 等建立映射关系,用于"丢失后找回" | 🔗[34] |
| 跨应用能力 | 灯塔自述拥有"海量的跨应用用户 ID 关系积累,以及实时的 ID 找回能力" | 🔗[34] |
| 采集字段 | IP、手机型号、网络类型、AndroidID、应用进程信息、OAID、IDFV、IDFA、ODID(Harmony)、AAID | 🔗[33] |
| 权限代价 | 仅网络类权限(INTERNET / ACCESS_NETWORK_STATE)+ HarmonyOS 的 APP_TRACKING_CONSENT(取 OAID) | 🔗[33] |
| 刷新机制 | Qimei36 默认为空,需联系灯塔开通;官方文档称"Qimei36 每隔 24 小时刷新一次" ⚠ 是否真变值需实测确认 | 🔗[31][32] |
| 接入门槛 | 硬门槛:需在腾讯开放平台注册游戏并通过审核,或由腾讯接口人内部注册;灯塔接入权限须经腾讯运营接口人 / "灯塔小秘"申请;appKey 在 Android 端一般是 QQ 号、iOS 是 i+QQ 号 | 🔗[31][32] |
12.2 反作弊场景下腾讯怎么用设备标识
十三、推送 SDK 的唯一 ID 全景(个推 / 极光 / 友盟 / 阿里 / 腾讯 / 厂商 / FCM)
用户提醒得对:推送 / 统计 SDK 是最典型、最普遍的"必须有唯一 ID"场景,而且——厂商内部确实维护"设备级 / 跨 App"的唯一 ID。本报告此前断言"所有推送 SDK 的 ID 都是应用级、没有一家提供设备级/跨 App ID",经复核是错误的,现作如下更正。
| 厂商内部分层 | 应用级(对外给开发者) | 设备级 / 跨 App(内部或需申请) | 同开发商级 |
|---|---|---|---|
| 个推(每日互动) | CID(ClientID) | GID(设备 ID)、卓信 ID(ZID,跨 App) | AID:aaid(应用级)/ vaid(同开发商多 App) |
| 极光 | RegistrationID(RID) | 脱敏的"终端用户设备唯一性标识"(合并链路/统计/画像按其计算) | — |
| 友盟 | Device Token | UMID(友盟设备唯一标识)、UTDID(阿里系,可跨 App 共享) | — |
| 阿里 EMAS | Token(厂商通道) | UTDID(跨 App 共享)→ DeviceID(对外唯一设备 ID) | — |
| 厂商推送(华为/小米/OPPO/vivo/荣耀) | Token / RegId / PushId | OS 厂商本身持有设备级 OAID / AAID / 设备标识 | — |
🔗 该分层结论来自个推隐私政策/合规指南与卓信 ID 文档、极光隐私政策/合规指引/社区、友盟 UMID 文档、阿里云 EMAS 设备标识文档、华为 OAID 官方文档(详见来源清单)。
各家的具体标识与稳定性如下:
| 推送服务 | 标识名称 | 作用域 | 生成方式 | 关键稳定性 / 失效条件 | 来源 |
|---|---|---|---|---|---|
| 个推 Getui | CID(ClientID,对外) GID(设备 ID) 卓信 ID(ZID,跨 App 设备级) AID:aaid / vaid |
分层:CID 每 App 一个;GID 为设备 ID;卓信 ID 是设备级——同一设备 1 个月内(约)不同 App 取值相同;aaid 仅同 App 不变、vaid 同开发商多 App 不变 | 客户端注册取得;卓信 ID 由 SDK 采集设备弱特征 → 服务端图计算聚类生成 RootID → 下发 ZID(有效期约 1 个月,过期自动重生成,可被用户清空) | CID 写入 SD 卡 → 正常卸载重装通常不变;90 天 / 1 年不活跃失效 | 🔗 个推隐私政策 / 合规指南 / 卓信 ID 文档 |
| 极光 JPush | RegistrationID(RID,对外) | 厂商内部另有"脱敏的终端用户设备唯一性标识"(设备级),官方明说用于"生成脱敏的终端用户设备唯一性标识",且推送、数据统计与用户画像均按其计算 | RID 由 JPush 服务端注册后下发;内部用 DeviceID(存 Settings + 外部存储)为主,可选 IMEI/MAC/IMSI 作"唯一设备标识的补充" | Android 卸载重装基本不变;iOS 每次重装都变(除非启用 IDFA)。官方明确用 WRITE/READ_EXTERNAL_STORAGE "避免对同一用户生成多个 RID、避免重复推送" |
🔗 极光隐私政策 / 合规指引 / 社区 |
| 友盟 UMeng | Device Token(推送) | UMID——官方定义为"友盟生成的设备唯一标识";友盟统计的"新增用户 = 独立设备数"即以 UMID 计(设备维度)。阿里系 UTDID 官方称可跨 App 共享 | Device Token 服务端生成;UMID 由友盟自研设备 ID 生成算法产出;UTDID 客户端算法生成并持久化 | UMID 在 App 生命周期内保持稳定唯一;UTDID 存 Settings + SD 卡 + 私有目录三份 | 🔗 友盟文档 / 阿里云 UTDID 文档 |
| 阿里 EMAS 移动推送 | Token(厂商通道) | UTDID + DeviceID——两者都是"设备级":UTDID 官方明确"利用系统中的公共存储组件,能够保证系统中不同的应用之间可以共享 UTDID";DeviceID 是 EMAS 对外暴露的唯一设备 ID(按标签/别名/账号推送最终都解析成 DeviceID) | UTDID 客户端算法生成 → 上报服务端 → 服务端据 UTDID 生成 DeviceID 下发;Token 与 DeviceID 一对一绑定 | UTDID 存 Settings + SD 卡 + 私有目录三份;DeviceID 过期:Android 90 天、iOS 24 个月 | 🔗 阿里云 EMAS 设备标识体系 |
| 腾讯 TPNS | Token | 单设备(每 App) | SDK 注册后服务端下发 | token 字符串长度 36 | 🔗[47] |
| 小米 MiPush | RegID | "唯一标识某台手机上的某个应用" | 服务端按 设备标识 + appID + 时间戳 生成 | 存本地 shared_prefs;卸载重装/清数据即变;30 天无长连接失效 | 🔗[46] |
| 华为 / 荣耀 / FCM | Token | 每 App | 厂商服务端下发 | 同 FCM 规则 | 🔗[42] |
| OPPO / vivo | RegId | 每 App | 厂商服务端下发 | 注册后回调取得 | 🔗[42] |
| 魅族 | PushId | 每 App | 厂商服务端下发 | — | 🔗[42] |
| Firebase FCM | Registration Token(正被 FID 取代) | 每个 App 实例一个(一设备多 App 多 token) | FCM SDK 首次启动生成,基于 App ID + 设备 ID + Google 账号 | 重装 / 清数据 / 换 Google 账号 / 换机恢复即变;≤4096 字符 | 🔗[48][49] |
| Apple APNs | Device Token | 每 App | APNs 下发 | iOS 9+ 卸载重装 token 变化 | 🔗[38] |
- 对外是应用级,内部是设备级:给开发者用的 CID / RID / RegID / Token 是应用级;但厂商内部都存在设备级(跨 App)唯一 ID——个推 GID 与卓信 ID、极光的"设备唯一性标识"、友盟 UMID、阿里 UTDID/DeviceID。这是为了在同一台设备的多个 App 之间去重(官方措辞:"避免对同一用户生成多个推送目标 ID"、"生成唯一的推送目标 ID(CID)和设备 ID(GID)")。
- 它们确实具备"跨 App 设备识别"能力:极光/个推的"合并链路"(同一设备多个 App 的推送链路合并成一条)与"卸载分析""同一设备 1 个月内不同 App 的卓信 ID 相同",都是跨 App 设备级识别的直接证据;卓信 ID 更进一步做到"跨 APP、小程序、H5 打通"。
- 都在拼命做"跨重装存活":把生成的 DeviceID 写到 SD 卡 / Settings.System / 外部存储 / 私有目录(个推写 SD 卡、极光写 Settings+外部存储、阿里 UTDID 写三份)——卸载不会清这些位置。这是"零权限换持久性"的关键 trick。
- 底层都吃 IMEI/MAC/AndroidID/Serial 做去重补充:极光把 IMEI/MAC/IMSI 列为"对唯一设备标识的补充",用于"提升唯一设备标识的准确性"。
🔗 各条均来自对应厂商官方文档/开发者社区原文(见来源清单)。
十四、互联网大厂自建设备 ID 体系
把调研拉通看,几乎每一家有规模的公司都自建了一套"设备 ID 中台",而不是直接用一个系统标识符。下面按公司归类(仅收录能查到一手公开资料的):
| 公司 / 体系 | ID 名称 | 作用域 | 核心做法 | 来源 |
|---|---|---|---|---|
| 腾讯 · 灯塔 | QIMEI / QIMEI36 / QIMEI16 | 设备级(腾讯生态内跨应用) | SDK 采集多源 ID 上报 → 后台 ID 关系库 + 山寨库 + 校准算法实时生成/找回并下发;与 IMEI/MAC/IMSI/AndroidID 建映射 | 🔗[30][34] |
| 腾讯 · 灯塔/MIG | GUID | 应用级 | 服务器端根据上报的 IMEI/IMSI/MAC/AndroidID 生成唯一 ID,并具备简单找回能力(QQ浏览器/应用宝/手机管家各自自建) | 🔗[34] |
| 阿里 · 友盟/mPaaS | UTDID / UMID | UTDID 号称可跨 App 共享(通过系统公共存储组件) | 首次调用用算法(AndroidID/随机数/时间戳等,新版已不取 IMEI)生成,持久化到 Settings + SD 卡 + 私有目录三份;官方承认"不能保证绝对唯一性" | 🔗[42][43] |
| 阿里 · EMAS 推送 | UTDID → DeviceID → Token | DeviceID 为对外唯一设备 ID | 服务端用 UTDID 生成 DeviceID,再与厂商 Token 一对一绑定;推送时统一解析成 DeviceID 下发 | 🔗[42] |
| 个推 / 极光 / 友盟推送 | 对外 CID / RID / DeviceToken;内部另有 GID / 卓信 ID / 设备唯一性标识 / UMID | 对外应用级,内部设备级 | 第三方推送各自建了"多源 ID 采集 + 服务端 uid 映射 + 本地多份存储"的找回体系,并在服务端维护设备级唯一 ID 做跨 App 去重与统计 | 🔗[38][39][44] + 十三节来源 |
| 字节 / 火山引擎 | (内部 Device ID) | — | ⚠ 未找到一手公开技术文档;公开检索到的多为产品/营销内容,此处不下结论、不编造 | ⚠ |
注:网易 / 美团 / 京东 / 字节亦有内部设备 ID 体系 —— 本版已定向补齐,详见 第十七节 与 第十八节「大厂内部设备 ID 体系专题」(字节 / 火山引擎有官方明文证据;京东有"与主站打通"的 okuuid 机制;网易有易盾设备 DNA 指纹;美团有 mtguard 设备指纹与 unionid 跨 App 归一;阿里 UTDID→DeviceID + 设备风险识别;快手 did/EGID;拼多多 anti_content/anti-token)。
十五、共同设计范式与最终修正结论
把腾讯 QIMEI、阿里 UTDID/EMAS、个推 CID、极光 RID 拉通看,它们无一例外遵循同一套五步范式。这就是"要跨客户端唯一 ID"的业界标准答案,也印证了本报告第九节的推荐架构:
| 步骤 | 做法 | 实例 |
|---|---|---|
| ① 采集多源 ID | 把能拿到的 ID 全采集:AndroidID / OAID / GAID / IMEI(旧) / MAC / Serial / IDFV / IDFA / 型号 / 进程信息 | QIMEI、极光、阿里 UTDID |
| ② 上报服务端 | 客户端只上报,不做最终判断 | 全部 |
| ③ 服务端合成 | 用 ID 关系库 + 找回算法 生成/找回一个稳定唯一 ID 并下发 | QIMEI(关系库/山寨库/校准)、阿里 DeviceID、极光 uid |
| ④ 本地多份存储 | 把结果写入 Settings / SD 卡 / 外部存储 / 私有目录 / Keychain,尽量跨卸载存活 | 个推写 SD 卡、极光写 Settings+外存、阿里写三份 |
| ⑤ 映射表维护 | 服务端维护"多源 ID ↔ 唯一 ID"映射,处理重置、换机、找回 | 全部 |
- 唯一 ID 不是"取出来的",而是"合成出来的"。任何依赖单一系统标识符的方案都必然被系统版本/厂商 ROM/权限变更打破。业界统一答案是客户端采集多源 → 服务端合成 + 找回 → 本地多份存储。
- 作用域决定选择:同开发商跨 App → IDFV / Keychain Group / App Set ID / ANDROID_ID;跨开发商设备级(国内)→ OAID;跨开发商设备级(海外)→ GAID/IDFA 或账号;全局 → 不存在合规方案。
- 推送 SDK 的 ID 要分两层看:对外给开发者的是应用级(CID/RID/RegID/Token,用于在同一 App 内识别安装);但厂商内部都维护"设备级 / 跨 App"ID(个推 GID 与卓信 ID、极光设备唯一性标识、友盟 UMID、阿里 UTDID/DeviceID),靠"多源采集 + 服务端合成"实现。因此要"跨客户端唯一",要么接入同生态的设备级 ID(如卓信 ID/AID,但有效期短、需接入体系),要么自建同款中台,不能指望某个对外的应用级 ID 直接满足。
- 腾讯 QIMEI 是这条路线的最佳工业实现,但接入门槛绑定腾讯生态;非腾讯系产品建议照抄它的范式自建中台,而不是试图接入 QIMEI。
- 落地时零权限优先:OAID / App Set ID / ANDROID_ID / IDFV / Keychain / MediaDrm 均零权限;把权限代价压到最低,同时用服务端合并兜住重置与换机。
十六、细分行业全景:哪些行业 / 场景也需要唯一 ID
「唯一 ID」不是游戏或推送 SDK 的专利,而是几乎所有数字化行业的横向刚需。本节把值得关注的细分行业/场景全部铺开,按需求本质归类为六个集群:广告与增长、安全风控与反欺诈、用户身份与运营、物联网与硬件、公共治理与实名、基础设施。
集群 A:广告与增长(归因 / 投放 / 跨设备)
| 细分行业 / 场景 | 典型用途 | 用什么唯一 ID | 权限 / 门槛 | 来源 |
|---|---|---|---|---|
| 移动广告归因(MMP) Adjust / AppsFlyer / Branch / Singular / Kochava |
判断这次安装来自哪条广告、跨会话去重、防作弊 | IDFA / GAID / OAID 作锚点,MMP 另外自建一个永久 UUID 存进 Keychain,把多个 ID 映射到同一用户 | iOS 取 IDFA 需 ATT 弹窗授权(约 15% 用户开 LAT 后取不到);Android 需 AD_ID 权限;国内 OAID 需 MSA 企业注册 |
🔗 Adjust 归因检查表 / MMP 指南 |
| Web 广告投放 / 受众定向 DSP / SSP / 媒体平台 |
跨站识别同一个浏览器或同一个人,做定向与频次控制 | 第三方 Cookie(正被主流浏览器淘汰)→ UID2.0 / RampID(以邮箱哈希为核心的跨站假名 ID) | Cookie 逐步退场;UID2/RampID 需广告主、媒体多方接入同一套规范 | 🔗 FTC PrivacyCon 2022 / W3C 指纹指南 |
| 短剧 / 内容出海(2024–2025 爆发赛道) | 算清 ROI、再做营销、按"钩子"精准召回 | 设备 ID(IDFA/GAID)+ 点击 ID(fbclid / gclid / _fbp)+ 一方数据,多触点归因 | 同 MMP;越依赖付费买量,越依赖这套 ID | 🔗 AttriTouch 自建归因 / Adjust 短剧 |
⚠ 说明:MMP 是"设备 ID 的消费者"而非生产者,它们同时用广告 ID + 自建 UUID 兜底,正是因为广告 ID 可被重置——这与本报告第四、九节结论一致。
集群 B:安全风控与反欺诈(设备指纹是主战场)
| 细分行业 / 场景 | 典型用途 | 用什么唯一 ID | 权限 / 门槛 | 来源 |
|---|---|---|---|---|
| 金融 / 银行 / 消费金融风控 同盾 / 顶象 / 数美 / 邦盛 / 白骑士 / 网易易盾 |
识别多头借贷、盗刷、团伙欺诈、羊毛党 | 设备指纹:采集硬件/软件/网络多维特征,服务端哈希 + 相似度比对,返回 hardId / token |
采集字段极多(型号、分辨率、Canvas/WebGL、字体、时区、网络…);IMEI/MAC/GPS 等为可选字段,需用户授权,未同意时不得采集 | 🔗 顶象文档 / 数美 / 厂商盘点 |
| 电商 / 营销活动反羊毛 | 识别小号、刷单、批量注册、活动套利 | 设备指纹 + 账号 + IP + 行为画像(多因子) | 同设备指纹;风控后台还常做"关系图谱"团伙挖掘 | 🔗 顶象解决方案实践 |
| 银行 / 支付 强认证 | 大额转账设备绑定、防止 U 盾/证书被盗用 | U 盾 / 手机盾等数字证书(本质是"一设备一证书"的硬件/软件身份) | 需实体介质或证书载体;手机盾因兼容性/使用率问题正被多家银行下线(农行 2026-01 起终止) | 🔗 工银 U 盾 / 证券时报 |
| 游戏反外挂 / 工作室检测 | 封禁作弊设备、识别模拟器与多开 | 设备指纹 + 登录设备画像(腾讯 ACE / 天御 TDS 用 DeviceToken 换可信设备标识) | 零权限优先 | 🔗 见第十二 / 十三章 |
集群 C:用户身份与运营(跨渠道归一 / 防共享)
| 细分行业 / 场景 | 典型用途 | 用什么唯一 ID | 权限 / 门槛 | 来源 |
|---|---|---|---|---|
| 电商 / 集团数据中台 阿里 OneData、多品牌集团 |
跨渠道、跨端的用户画像打通、打破数据孤岛 | OneID / ID-Mapping:把手机号、邮箱、Cookie、IMEI/IDFA、账号、设备 ID 等映射到统一 ID | 需在告知同意前提下整合;数据合规要求高 | 🔗 阿里 OneID / 龙石数据 |
| 会员 / CRM / CDP | 多套会员体系权益打通、精准触达 | OneID(GrowingIO 等提供"全域实时可配置"的身份融合) | 同 OneID;规则需可配置以适应业务调整 | 🔗 GrowingIO OneID |
| 视频 / 内容会员(防账号共享) | 限制同时在线设备数、打击租号黑产 | IP + 设备 ID + 账户活动三者结合判断(Netflix 明确披露) | 设备数上限由平台策略定义(腾讯视频 VIP 3 台、爱奇艺 5 台等) | 🔗 21 世纪经济报道 / 界面新闻 |
| 微信生态(公众号 / 小程序 / 移动应用 / 企业微信) | 同一个自然人在多端被识别为同一人(与本报告主题最贴近的一类) | openid(单个应用内唯一)→ unionid(同一开放平台账号下跨应用唯一) |
需把多个应用绑定到同一个微信开放平台账号;部分获取路径需用户授权,部分(如已关注公众号)可免授权 | 🔗 微信开放文档 |
集群 D:物联网与硬件(设备身份 / 一物一码)
| 细分行业 / 场景 | 典型用途 | 用什么唯一 ID | 权限 / 门槛 | 来源 |
|---|---|---|---|---|
| 工业互联网(制造、石化、汽车、电子…) | 零部件/机器/产品的全生命周期追溯、供应链协同 | 工业互联网标识:主流体系含 Handle / OID / Ecode / VAA,由国家顶级节点 + 二级节点解析 |
需接入标识解析体系(申请二级节点/注册服务);工信部有《标识管理办法》许可要求 | 🔗 工信部 行动计划 / 管理办法 / GB-T 38662 |
| 智能家居(Matter 生态) | 设备配网、跨生态(苹果/谷歌/亚马逊)互通控制 | 配网信息 Vendor ID + Product ID + discriminator + setup passcode → 配网后获得 Node ID + Fabric ID + NOC 证书;设备认证用 DAC 证书 | 产品需通过 Matter 认证;Wi-Fi/Thread 方案需对应联盟认证 | 🔗 CSA Matter / Nordic Matter 指南 |
| 车联网 / 汽车 | 车辆身份、保险定价、二手车估值、远程控制 | VIN 车辆识别代号(17 位,ISO 3779 / 3780 / 4030;中国 WMI 前缀 L) | 出厂固有,且 VIN 属"个人常用设备信息",受个保法约束 | 🔗 ISO 3779 / NHTSA / 锦天城律所解读 |
| 通用 IoT 设备管理 | 设备纳管、接入控制、固件身份 | 设备唯一标识/序列号(NIST 建议"每个 IoT 设备可被唯一识别") | 出厂写入;管理侧按设备身份做访问控制策略 | 🔗 NIST Federal Profile 8259A |
集群 E:公共治理与实名(法定身份标识)
| 细分行业 / 场景 | 典型用途 | 用什么唯一 ID | 权限 / 门槛 | 来源 |
|---|---|---|---|---|
| 数字身份 / 实名核验(政务、金融、社交) | 非明文核验自然人真实身份("可用不可见") | 网号 / 网证(国家网络身份认证公共服务,2025-07-15 施行);标准侧另有 CTID(GA/T 1724-2020) |
自然人自愿申领,需有效法定身份证件;平台自愿接入 | 🔗 国家网信办 / 公安部 GA/T 1724 |
| 电子证照 / 企业身份 | 企业唯一标识、证照真伪核验、跨部门共享 | 统一社会信用代码(18 位,GB 32100-2015,全国唯一终身不变);电子证照标识(GB/T 36904-2018) | 由赋码主管部门颁发;查询走国家企业信用信息公示系统 | 🔗 GB 32100 / 全国组织机构代码管理中心 |
| 医疗健康 | 患者跨院区/跨系统识别、一码就医购药结算 | 患者主索引 MPI / 跨域主索引 EMPI(IHE PIX 机制);医保码/医保电子凭证(全国统一、一人一码) | 医保码需身份认证+人脸识别激活;EMPI 需院内多系统集成;仅在多院区且需跨院区共享时才需要 EMPI(单体医院用 MPI 即可) | 🔗 卫健委 MPI 指南 / WS/T 840 / 国家医保局 |
| 游戏防沉迷 | 玩家实名、限制未成年时段与充值 | 实名认证(真实姓名+身份证号)+ 国家新闻出版署网络游戏防沉迷实名验证系统 | 所有网络游戏必须接入;不得以游客模式向未实名用户提供游戏服务 | 🔗 国家新闻出版署 |
集群 F:基础设施(本报告已有专章,此处仅列)
- 单点登录 / IAM:企业联邦身份用 SAML 2.0 / OpenID Connect;设备绑定凭据用 FIDO / WebAuthn("你拥有的设备"作为认证因子)。
- 数字版权 / DRM:Android
MediaDrm.PROPERTY_DEVICE_UNIQUE_ID(Widevine)零权限但兼容性差,Google 不推荐当通用主键——详见第四、五节。 - 推送 / 统计 SDK:对外 ID(个推 CID、极光 RID、友盟 DeviceToken、FCM Token)为应用级,但厂商内部均维护设备级(跨 App)ID(个推 GID/卓信 ID、极光设备唯一性标识、友盟 UMID、阿里 UTDID→DeviceID)——详见第十三章。
- 能真正做到"全局唯一 + 长期稳定"的,全是"身份类"ID,而不是"设备类"ID:法定身份(身份证号、统一社会信用代码、VIN、医保码、网号/网证)和平台账号(微信 unionid、业务账号 ID)。它们不依赖设备,因此不受重装、换机、系统升级影响。
- "设备类" ID 大多是可重置 / 概率性的:广告 ID 可重置、ANDROID_ID 随签名变化、设备指纹是"相似度打分"而非确定性 ID、IMEI/MAC 已被系统废弃。即便如此,业界仍造出了跨 App 的设备级 ID——如个推/信通院的卓信 ID(同一设备 1 个月内不同 App 相同,但有有效期、可被用户清空、需接入体系)与阿里 UTDID(官方称可跨 App 共享)。因此更准确的说法是:"零权限 + 跨开发商 + 长期稳定"三者不可兼得,而不是"设备级跨 App ID 不存在"。
- 风控行业早就接受了这个事实:它们不追求"取一个 ID",而是"多源采集 → 服务端合成/打分 → 风险标签",这正是本报告推荐架构的同类实现。
- 对"跨客户端同一 SDK 要唯一 UUID"的直接建议:最稳的锚点是服务端账号 ID(用户登录后下发)或平台身份(如微信 unionid);设备 ID / 设备指纹只能作为"辅助锚点 + 防作弊信号",用于登录前和未登录态的去重与关联。若必须纯设备级,就照抄第十五章的五步范式(采集多源 → 服务端合成 + 找回 → 本地多份存储 → 服务端映射表),而不是试图直接取用某一个系统标识符。
本节为桌面调研,覆盖行业为公开可查、且确实以"唯一 ID"为核心技术需求者;未穷尽所有长尾行业(如快递物流一物一码、网吧/酒店实名终端、共享出行设备管控等,其机制与集群 D/E 同类)。所有结论均标注来源,未做实测。
十七、大厂内部设备 ID 体系专题:字节 / 京东 / 网易 / 美团
上一版把网易 / 美团 / 京东 / 字节标为"未找到一手公开技术文档"。本轮定向补齐后确认:四家都把"设备 ID"做成跨业务线的中台能力,而不是直接取用某个系统标识符;做法依旧收敛到第十五节的五步范式(多源采集 → 服务端生成/找回 → 本地多份存储 → 服务端映射表)。其中字节(火山引擎)有官方文档明文写出"跨 App 同一 device_id",是本报告"跨客户端唯一 ID"可引用的最强一手证据;京东有明确的"与主站打通"机制;网易、美团则主要把设备级能力放在风控与账号安全侧。
17.1 字节跳动 / 火山引擎 —— 官方明文「跨 App 同 device_id」
火山引擎增长分析(DataFinder)官方文档把设备标识写成 device_id,并明确写出跨 App 一致:
—— 这正是本报告要找的"跨客户端唯一 ID":靠服务端设备注册服务(而非客户端各算各的)保证同一设备的不同 App 拿到同一个 device_id。
| ID | 类型 | 作用域 | 含义 / 生成 | 来源 |
|---|---|---|---|---|
| device_id | int | 设备级(跨 App) | 服务端"设备注册服务"按设备信息生成并下发;同一设备不同 App 相同;SDK 本地存储;不支持业务自定义 | 🔗[103] |
| web_id | int | 网页 / 小程序设备级 | 由 app_id + 当前 URL + referer + UA 生成 | 🔗[103] |
| user_unique_id | — | 登录用户 | 一般用业务登录账号;未设定时 SaaS 版自动用 device_id 顶替 | 🔗[103] |
| ssid | — | 集团级(开启"统一 ID 服务"后) | 统计口径 ID,与 device_id / user_unique_id 互相 Mapping,打通匿名与实名;未开统一 ID 服务时按应用粒度隔离 | 🔗[103] |
| anonymous_id | string | 自定义设备级 | 允许把自己的设备标识随 device_id 一起上报(iOS/Android 端不支持上报) | 🔗[103] |
| BDID | 64 位小写哈希 | 广告归因(按客户维度隔离) | "巨量引擎下的整合归一 ID,替换原来的设备 ID 宏字段(IMEI、IDFA、OPENUDID 等)……同一设备在不同客户维度下 BDID 不相同" | 🔗[104] |
补充:抖音 / 今日头条系的"设备注册"接口(device_register)返回 device_id(设备级,重装可存活)与 install_id / iid(每次安装一个),并把 openudid / clientudid / mac / google_aid / sig_hash 等作为注册因子;头条系与抖音系 App 共用同一套设备注册服务,因此同一设备跨 App 得到同一 device_id。⚠ 该细节来自第三方逆向分析,非官方文档,此处仅作佐证、不下绝对结论。🔗[125][126]
火山引擎面向外部提供的 SDK(穿山甲广告、增长营销套件、RangersAppLog 转化 SDK、业务安全套件设备安全 SDK)的采集字段清单,可佐证其底层同样是"多源 ID 采集 + 服务端生成":Android 采 OAID / AndroidID / GAID / MEID / ICCID / 硬件序列号 / MAC,iOS 采 IDFA / IDFV,鸿蒙采 AAID / OOID 等。🔗[122][123]
17.2 京东 —— okuuid:一个可"与主站打通"的设备 UUID
京东的设备 ID 能力有两条公开线索:对外产品化的"设备指纹",与内部的通用 SDK okuuid。
- 京东云 / 星盾 设备指纹:官方产品描述为"通过高稳定高兼容的设备指纹 SDK,为每一个访问您业务的移动设备建立全球唯一且稳定的设备 ID";产品优势写明"依托京东 20 余款 APP 的最佳实践及设备指纹能力的沉淀";产品功能"生成设备唯一标识"写明"通过采集到的设备数据,基于自研高可靠的生成和恢复算法,生成全球唯一的设备 ID,对抗黑产伪造和篡改",并附带 APP 多开 / root / 越狱 / 模拟器 / 云手机 风险检测。🔗[105][106]
- okuuid(京东内部通用 UUID 组件):EMOP 文档给出京东主站的 UUID 方案 ——
系统 < Android 10时 UUID =IMEI-MAC;≥ Android 10时优先用 APP 本地缓存的 UUID,未缓存则填 Android ID(零权限降级)。关键在于提供两个包:okuuid(普通)与okuuid-jdmall——文档原文:"如果存在与主站打通数据的需求,即 UUID 需要和主站保持一致,那么就采用以下方式引入"。🔗[108] - 京东会议 App 的第三方 SDK 清单里,
com.jingdong.wireless.jdsdk:okuuid被登记为"日志上报设备标识"的"内部 SDK",运营主体为京东叁佰陆拾度。🔗[109] —— 佐证 okuuid 已是京东内部跨 App 共享的设备标识。
17.3 网易 —— 易盾设备 DNA 指纹 + 集团基础 SDK 的 Device ID
- 网易易盾「设备 DNA 指纹」:官方定义为四大能力——设备标识(关联硬件 / 软件 / 网络 / 状态多维信息,用"加权 DNA 算法"生成唯一指纹)、智能追回(机器学习建模,无视设备信息篡改,追回同一指纹)、风险检测、设备信用体系。🔗[110][111]
- 服务端 vs 客户端两版:客户端版不与易盾服务器通信(适合信息敏感客户);服务端版有利于提高各端(含 H5、小程序)设备指纹的唯一性。🔗[111]
- 找回算法(官方技术文):用 F1/F2 多种算法各算一个指纹,再由服务端用历史数据回溯"找回"——A 字段变了靠 B 找到,B 变了靠 A 找到,最终 Sid 保持不变;官方披露线上实测"找回比例达 8.9%"。🔗[112]
- 采集字段与权限:Android 采 AndroidID / OAID / GAID / MAC(IMEI 自 SDK 1.7.2.3 后不再采集、SN 自 1.8.0 后不再采集),iOS 采 IDFV;仅需网络权限(非必须)。🔗[113]
- 网易集团内部:网易云音乐的第三方共享清单里,"网易基础 SDK"以"设备标识信息(Device ID)"用于"基本网络服务、安全风控、日志收集、注册登陆"——即网易集团有一个跨 App 的基础设备标识层;同时内嵌易盾设备安全 SDK 与信通院的 OAID 统一调用 SDK。🔗[114]
- ID-Mapping:网易产品线(云音乐 / 邮箱 / 新闻 / 严选)各有 ID(yanxuanid / oaid / musicid / phone / email / idfa / imei),用"连通图划分 + 社区发现"判断是否同一个人;设备有效期约 2.5 年、设衰减系数。⚠ 二手来源。🔗[121]
- 云音乐专利 CN122765062A:用"带唯一令牌身份标识的令牌"做在线设备数统计,摘要明确要解决"客户端程序无法生成设备 ID、设备 ID 冲突、设备 ID 分裂"等问题。🔗[115]
17.4 美团 —— mtguard 设备指纹 + unionid 跨 App 归一
- 隐私政策(官方):美团明确采集 设备型号 / 硬件序列号 / 设备 MAC / 唯一设备识别码(IMEI/MEID/IMSI/AndroidID/IDFA/IDFV/OAID/ICCID 等) / 运行中进程 / 移动应用列表 / 传感器 / WIFI 状态(SSID/BSSID)/ 运营商,用于"账号安全、交易安全、系统运行安全"与推送、防异常登录。🔗[116][117]
- 设备指纹(逆向佐证 ⚠):美团外卖 App 用 native 库
libmtguard.so(MTGuard)做设备环境检测与设备指纹,存在 xid 与 dfpid 两套设备指纹字段,"APP 第一次运行就用 UUID 与时间加密生成一个",并配合mtgsig请求签名做风控。🔗[119] - 跨 App 归一(逆向佐证 ⚠):美团 SSO 分析显示,美团系 App 因使用同一签名 → 共享同一个 AndroidID;客户端把 deviceInfo(品牌 / 型号 / android_id)换成 token 上报,服务器据此识别"该设备上还有其它已登录的美团 App",从而返回跨 App 共享的 unionid。🔗[120]
- 账号体系:注册用户以 手机号为唯一标识(美团 × 大众点评打通),未注册用户用 device ID 关联。⚠ 二手来源。🔗[121]
- 风控规则引擎 Zeus(官方技术博客):核心是在业务请求里识别"谁、在什么时间、通过什么方式、做了什么事"——设备 ID 是其中"谁"的底座。🔗[118]
17.5 四家横向对比
| 公司 | 设备级 ID | 跨客户端能力 | 是否对外 | 来源 |
|---|---|---|---|---|
| 字节 / 火山引擎 | device_id(ssid / BDID 衍生) | ✅ 官方明文:同一设备不同 App 相同 device_id(服务端设备注册服务保证) | ✅ 对外(DataFinder / 增长营销套件 / 穿山甲) | 🔗[103][104] |
| 京东 | okuuid UUID / 设备指纹 ID | ✅ okuuid-jdmall「与主站打通、UUID 保持一致」;20+ App 实践 | 部分(京东云设备指纹对外售卖) | 🔗[105][108] |
| 网易 | 易盾 DNA 指纹 Sid / 基础 SDK Device ID | ✅ 服务端版跨 H5 / 小程序提高唯一性;集团基础 SDK 统一 Device ID | 部分(易盾对外售卖) | 🔗[110][114] |
| 美团 | xid / dfpid(mtguard) | ✅ 同签名 AndroidID 共享 + unionid 跨 App 归一(逆向佐证) | 否(内部风控 / 账号安全为主) | 🔗[117][119][120] |
十八、大厂内部设备 ID 体系专题(二):阿里 / 快手 / 拼多多
承接第十七节(字节 / 京东 / 网易 / 美团),本节补齐阿里(在 UTDID / OneID 之外补其设备风险识别体系)、快手、拼多多三家。结论一致:仍然收敛到第十五节的五步范式,差别只在"是否有独立设备 ID、是否对外开放"。
18.1 阿里 —— UTDID(可跨 App 共享)+ 设备风险识别(DeviceToken)
- UTDID(应用级设备 ID,可跨 App 共享):官方原文"利用系统中的公共存储组件,能够保证系统中不同的应用之间可以共享 UTDID";首次调用由特定算法生成(AndroidID / IMEI(旧) / 随机数 / 时间戳 / 版本号 加密截断,新版因隐私不再取 IMEI),持久化到系统 Settings + 存储卡 + 应用私有目录三份;卸载重装 / 清缓存 / 恢复出厂 / 刷 ROM 都有可能改变。🔗[42]
- UTDID → DeviceID → Token(EMAS 推送):服务端用 UTDID 生成对外唯一设备 ID(DeviceID),并一对一绑定厂商通道 Token;DeviceID 过期 = 安卓 90 天 / iOS 24 个月。🔗[42]
- 阿里云「设备风险识别 / 设备风控服务」(对外的设备指纹中台):客户端 SDK 采集设备指纹 →
getDeviceToken()→ 业务服务端携带 deviceToken 调 API → 返回风险标签 + 评分。Token 约 600 字节(好网)/ 2.5K(弱网),带 "Tkxxxx / UFxxxx" 前缀;建议传bizId绑定业务 ID 防篡改。🔗[130][132] - 字段做了合规分级(可开关):① 可变更唯一设备标识码 = OAID / GAID / AndroidID;② 不可变更唯一设备标识码 = IMEI / IMSI / SimSerial / SN / MAC;③ 基础设备信息;④ 设备扩展信息(黑灰产 App 列表、局域网 IP、DNS IP、SSID / BSSID、附近 WIFI)。按 DataType 开关控制采集。🔗[131]
- 权限:
INTERNET必选;READ_PHONE_STATE与存储权限为"推荐(非必选)"。🔗[130] - 集团内「阿里安全(橙盾)」:用于 App 运行 / 网络请求 / 账号注册登录的安全防护,采集 IMEI / BSSID / SSID / Android ID / MEID / IMSI / 硬件序列号 / ICCID / MAC / 传感器 / 应用列表。🔗[133]
18.2 快手 —— did / EGID(设备注册服务)+ 隐私政策里的多标识采集
- 隐私政策(官方):浏览 / 播放内容时"记录设备信息(OAID、AndroidID、IDFA)";详细版进一步列明 设备标识信息(AndroidID、IDFA、IDFV、UAID(移动/联通/电信,仅安卓)、OAID、Openudid 及其他综合设备参数和系统信息形成的设备标识符)+ 设备参数(名称 / 型号)+ 软硬件系统信息(含应用软件安装列表)。🔗[127]
- 快手联运 SDK:
oaid明确标注为"生成设备标识"的必要字段;采集 设备标识符(OAID、GAID、Android ID、硬件序列号 SN、ICCID、IP、位置、传感器、网络、运行中进程)。🔗[128] - 设备标识 = did / EGID:短视频侧用
did(作为 cookie / 请求参数传递);App 侧走设备注册服务获取 EGID。逆向资料显示:注册请求携带productName=KUAISHOU、ts、deviceInfo、sign、rdid,构造约 119 个字段的设备参数对象;当取不到设备号时按"系统 AndroidID → 无效则SecureRandom生成 16 位随机 → 格式化为ANDROID_xxxxxxxxxxxxxxxx→ 存 SharedPreferences(new_random_android_id)"兜底。⚠ 逆向佐证,非官方文档。🔗[129]
18.3 拼多多 —— anti_content / anti-token(设备标识捆在风控签名里)
- Web / 小程序侧
anti_content:被描述为接口的"通行证",融合时间戳 + 浏览器/设备指纹 + 轻量操作轨迹 + 动态加密盐,每次请求重新生成,并检测是否运行在真实浏览器环境(window / navigator / canvas / WebGL 等近百个属性)。🔗[135] - App 侧
anti-token:由com.xunmeng.pinduoduo.secure.DeviceNative.deviceInfo2(context, timestamp)生成,落到 native 库libpdd_secure.so(OLLVM 混淆);另有SecureNative / DeviceNative.info4= "2ag" + Base64(AES-128-CBC(...)) 的自定义 TLV 二进制,内含约 33 个字段的设备信息。🔗[134] - 开放平台侧:商家解密订单触发风控时,走"风控验证码 + 前端检测 SDK(pc.js)"解除,检测结果周期上报。🔗[136]
- 结论:拼多多不对外提供通用设备 ID,设备指纹直接服务于服务端强风控 + 客户端强混淆,属于第十节"合规红线"里最激进的一类,做 SDK 时不宜照搬。
18.4 三家横向对比
| 公司 | 设备级 ID | 跨客户端能力 | 是否对外 | 来源 |
|---|---|---|---|---|
| 阿里 | UTDID → DeviceID;设备指纹 DeviceToken | ✅ UTDID 经系统公共存储组件在阿里系 App 间共享 | ✅ 阿里云设备风险识别 / 设备风控服务对外售卖 | 🔗[42][130] |
| 快手 | did(短视频侧)/ EGID(设备注册服务) | ~ 设备注册服务下发 EGID(逆向佐证);隐私政策列多标识采集 | ❌(隐私政策 + 联运 SDK 采集为主) | 🔗[127][128][129] |
| 拼多多 | anti_content / anti-token(非独立设备 ID) | ~ 捆在风控签名内,不暴露设备 ID | ❌ | 🔗[134][135] |
十九、设备识别特征全谱:除了 ID,还有哪些特征能鉴别设备
标识符(ID / Identifier)——操作系统或厂商主动分配的、语义上就代表"这台设备 / 这个安装"的值(OAID、IDFV、ANDROID_ID…)。它可能被限制、被重置、被废弃。
特征(Feature / 指纹)——设备在使用过程中无意泄露的旁路信号(IPv6 地址、TLS 握手参数、GPU 渲染结果、传感器校准误差…)。不需要谁去"分配",也无法简单开关。
本节回答的是:当 ID 被系统限制(Android 10+ 废弃 IMEI/MAC、iOS 移除 UDID、ATT 限制 IDFA)之后,业界还靠哪些特征来鉴别设备。核心规律只有一条:单个特征几乎都不唯一,把多个特征的"熵"叠加起来才唯一(熵可加的算术见 19.4)。
19.1 六大类特征总览
| 类别 | 典型特征 | 鉴别粒度 | 谁看得见 | 稳定性 |
|---|---|---|---|---|
| A 网络层 | IP(IPv4/IPv6)、TLS(JA3/JA4)、HTTP/2、TCP/IP 栈(p0f/JA4T)、DNS、WebRTC 本地 IP、DHCPv6 DUID | OS / App 类别为主;IPv6 可到设备 | 服务端被动可见(DUID 仅 ISP 侧) | 低(换网即变) |
| B 硬件 / 物理层 | GPU 渲染 & 执行单元时序、传感器出厂校准、时钟偏移、电池、音频编解码、Wi-Fi / BT 射频 | 可到单台设备(最强) | 部分可(App / 网页) | 极高(刷机 / 恢复出厂都不变) |
| C 软件 / 系统层 | Build.*(FINGERPRINT / MODEL / HARDWARE…)、系统属性 getprop、内核版本、Boot ID、CPU(/proc/cpuinfo)、内存、屏幕、传感器列表、相机 | 机型 / 系统版本为主 | ✅ 零权限 | 中(升级即变,Boot ID 重启即变) |
| D 浏览器 / 运行时 | Canvas、WebGL、AudioContext、字体、时区、屏幕、UA / HTTP 头、插件、语言 | 可到单台设备 | 仅网页 / WebView | 高(组合熵 >18 bit) |
| E 环境 / 行为 | Wi-Fi BSSID / SSID 邻居快照、BLE 广播、应用安装列表、运行中进程、传感器行为、触摸 / 按键时序 | 可到单台设备 | 需位置 / 查询权限(版本相关) | 中高(环境变化才变) |
| F 存储残留 | Cookie / localStorage / IndexedDB / ETag / HSTS supercookie / 缓存;iOS Keychain;Android 外部存储 & Settings | 到安装 / 设备 | ✅ | 卸载可清(Keychain / Settings 例外) |
注:B / D / E 三类是"设备指纹"的主力;A 类多用于识别"是不是同一类客户端 / 是否被代理",区分个体弱;C / F 类属传统采集。来源见来源清单 [137]–[156]。
19.2 网络层特征(你点名的 IPv6 在这一节)
IP 地址(IPv4 / IPv6)
IPv4:NAT / CGNAT 之后大量用户共享一个出口 IP,无法区分个体;移动网络尤其如此。IPv6 之所以被单独讨论,是因为 SLAAC(无状态地址自动配置,RFC 4862)生成的"稳定地址" = 路由前缀 + 接口标识(IID),而 IID 常常长期不变——只要地址不变,服务端就能把多次访问关联到同一主机,这就是"IPv6 地址能当设备标识"的由来。RFC 7721 明确讨论了 IPv6 地址生成机制的隐私影响,指出固定 IID 会导致"基于地址的网络活动关联"。🔗[138]
标准里也早给了两种缓解(都已落地):
- RFC 8981(临时地址,正式取代 RFC 4941):为每个前缀生成随机 IID 的临时地址并定期轮换(默认 24 小时),使"同一主机不同事务"难以用地址关联。🔗[137]
- RFC 7217(语义不透明 IID):用"密钥 + 前缀 + 网络接口"派生出"同一网络内稳定、但跨网络不可预测"的 IID,兼顾稳定与隐私。🔗[139]
现实判断:运营商常按用户分配稳定的 IPv6 前缀(如 /56、/64);若终端未启用临时地址,则"前缀 + IID"在较长时间内是准稳定的设备关联锚点;反之 iOS / Android 默认开启隐私扩展后地址会轮换,鉴别力大幅下降。⚠ 结论:IPv6 地址是"短期关联 / 弱锚点",不是可靠的设备 ID;且服务端只能看到出口地址,跨 NAT64 / 双栈 / CGNAT 会失真。
DHCPv6 DUID(RFC 8415)
DHCPv6 用 DUID 标识客户端,标准要求它"跨重启稳定":DUID-LLT = 链路层地址 + 时间戳,DUID-UUID(RFC 6355)= 系统 UUID,DUID-EN = 企业号 + 厂商信息。🔗[140][141] 但 DUID 只在网络侧(DHCP 服务器 / 运营商)可见,App 拿不到,且重装系统 / 多系统并存会变。⚠ 对 SDK 无直接可用性,仅作背景知识。
TLS 指纹 JA3 / JA4
TLS 的 ClientHello 是明文发送的,其密码套件、扩展、ALPN 由客户端 TLS 库决定 → 可识别"哪个应用 / 哪个 TLS 库"。JA4(FoxIO,JA3 的继任者)对扩展排序稳健、支持 QUIC、人类可读(a_b_c 三段)。🔗[142] 但 Cloudflare 官方文档明确指出:移动 App 的流量往往在不同设备、不同用户上产生相同的 JA3 → 它适合识别"这是不是你的 App",不适合区分个体设备。🔗[143]
HTTP/2 指纹(Akamai)与 TCP/IP 栈指纹(p0f / JA4T)
HTTP/2 指纹格式为 SETTINGS|WINDOW_UPDATE|PRIORITY|伪头顺序,由客户端实现决定,服务端被动生成。🔗[144] TCP/IP 栈指纹看 SYN 包里的初始 TTL(64/128/255)、窗口大小、MSS、TCP 选项顺序——这些由内核决定、应用无法控制,用于识别 OS,并可用于发现"User-Agent 与 TCP 栈不一致"的代理 / 伪造。🔗[145] 两者都偏"OS / 客户端实现识别",区分个体弱。
WebRTC 本地 IP
ICE candidate 会带出私网 IP,而"私网 IP + 公网 IP 组合常可唯一标识一台设备",故 IETF 用 mDNS 随机主机名遮蔽(草案原文:knowing both the private IP address and the public IP address will usually identify uniquely the user device)。🔗[146]
19.3 硬件 / 物理层特征(最强、最难改)
- GPU 渲染指纹(Canvas / WebGL):由 GPU + 驱动 + 字体栅格化 + 抗锯齿共同决定;读原始像素时跨浏览器稳定。Canvas 约 8–10 bit,WebGL renderer 约 6–8 bit(渲染串最多约 10 bit)。🔗[147]
- DrawnApart(NDSS 2022):利用同一 GPU 内多个执行单元的速度差异(制造公差),用 WebGL 时序测量把 GPU 指纹从"型号级"提升到"单颗芯片级",中位追踪时长 +67%;后续 WebGPU 版(LockedApart)最快 310×、准确率最高 1.8×。🔗[148]
- 传感器出厂校准指纹(SensorID / Factory Calibration Fingerprinting):从陀螺仪 / 加速度计 / 磁力计输出反推每台设备的出厂校准增益矩阵,构成"用户无法更改、恢复出厂也不变"的设备指纹;iOS 约 67 bit 熵(iPhone 6S),Pixel 4/4 XL 约 57 bit;无需任何特殊权限,App 与网页都能生成。Apple 在 iOS 12.2 加随机噪声(CVE-2019-8541)、Google 在 Android 11 取整缓解(均非完美)。🔗[149]
- 时钟偏移(clock skew):由晶振制造公差决定,ppm 级、长期稳定、难伪造;经典方法用 TCP / ICMP 时间戳推算(Kohno 2005 思路),实测 100 台设备偏移分布 67 ~ −499 ppm 可区分。🔗[150]
- 其他:电池状态 / 充电曲线、音频编解码(扬声器–麦克风频响)、相机 sensor 噪声模式。
19.4 浏览器 / 运行时特征(熵叠加的算术)
- Canvas ≈ 8–10 bit、WebGL ≈ 6–8 bit、AudioContext ≈ 4–5 bit,三者同会话合计 >18 bit → 足以从约 25 万用户中唯一识别。🔗[147]
- 唯一性实证(INRIA AmIUnique,约 200 万指纹):桌面浏览器 35.7% 唯一、移动 18.5% 唯一;90 天后 89% 指纹仍可唯一识别;时区是"跨浏览器 100% 稳定、3.51 bit"的最可靠低熵信号。🔗[147]
- ⚠ 提醒:这些是"浏览器指纹"的数字,与"跨 App 设备 ID"不是一回事;不同来源口径差异大(部分为厂商自报),引用需谨慎。
19.5 环境 / 行为特征
- Wi-Fi BSSID / SSID 邻居快照:一次扫描到的 BSSID 集合即可唯一识别约 99% 的用户;仅"信号最强的 1 个 AP"的 BSSID 就能重识别 >90%,top-2 >97%;SSID top-2 约 97%。🔗[151]
- BLE 地址随机化可被 RSSI 分布破解:用广播包的 RSSI 分布训练分类器,在 ≤30 台静止设备场景下重识别准确率约 0.99。🔗[152]
- 应用安装列表 / 运行中进程 / 剪贴板 / 触摸与按键时序 / 传感器行为模式。
19.6 软件 / 系统层特征(Android 为例)
Build.*全家桶:FINGERPRINT、MODEL、BRAND、DEVICE、HARDWARE、HOST、BOARD、DISPLAY、TYPE、getRadioVersion();系统属性getprop(ro.build.*、ro.boot.*);内核版本、Boot ID(重启即变)、/proc/cpuinfo、内存、屏幕、传感器列表、相机、安装包列表。🔗[153]- 模拟器识别就是靠这些:
Build.FINGERPRINT以generic/开头、/proc/cpuinfo含ranchu/goldfish/qemu、ro.kernel.qemu等。🔗[153] - ⚠ 采集对抗已"军备化":同一字段分别用 Java API / native libc / 直接 syscall 三层读取并交叉比对,用于发现 Xposed / Frida 篡改(见开源项目 device fingerprinting 模块,⚠ 第三方来源)。
19.7 特征 → 取舍综合表
| 特征 | 鉴别粒度 | 稳定性 | 采集代价 / 权限 | 对 SDK 的可用性 |
|---|---|---|---|---|
| IPv6 / IP 地址 | 弱锚点 | 换网即变 | 服务端被动 | ⚠ 仅作辅助信号,不作主键 |
| TLS / HTTP2 / TCP 栈 | OS / App 级 | 中 | 服务端被动 | 识别自家 App / 反代理,区分个体弱 |
| GPU 渲染(Canvas / WebGL) | 设备级 | 高 | 网页即可 | 反作弊可用,隐私敏感 |
| 传感器校准 | 设备级(最强) | 极高(恢复出厂不变) | 零权限 | 已被系统缓解(iOS 12.2 / Android 11);合规风险高 |
| Wi-Fi BSSID 快照 | 设备级 | 中高 | 位置权限 | ⚠ 合规风险最高(等同精确定位) |
| Build / 系统属性 | 机型级 | 中 | 零权限 | ✅ 可作机型分布统计,非唯一 |
| Canvas / WebGL / Audio | 设备级 | 高 | 网页 / WebView | 属浏览器指纹;App 内 WebView 可采集 |
19.8 对 SDK 的落地建议(合规红线)
② 正确用法:只作服务端风险评分 / 异常检测的辅助维度(与官方 ID、账号组合),不做唯一主键;采集须遵循"最小必要 + 明示同意 + 服务端合成 + 不落盘明文"。
③ 技术现实:"跨卸载 + 跨开发商 + 零权限 + 长期稳定"四者不可兼得——特征指纹牺牲的是"用户可控 / 合规",换来的是"难重置",代价是随时可能被系统版本更新抹平(iOS 12.2 加噪声、Android 11 取整就是先例)。
④ 选型口诀:要"合规 + 跨 App",用官方 ID(OAID / IDFV / App Set ID,见第四~六节);要"难重置 + 设备级",那是风控厂商的活(顶象 UnifyID / 同盾北斗 / 数美 / 网易易盾,⚠ 厂商自述口径),且必须自担合规责任。🔗[154][155][156]
二十、算法逐个拆解:每个 ID / 指纹到底是怎么算出来的
21.0 总览:九类算法家族
| 算法家族 | 代表 | 输入 | 输出形态 | 性质 |
|---|---|---|---|---|
| 带密钥 MAC | ANDROID_ID (SSAID) | 签名证书 + 该用户的随机密钥 | 16 位十六进制 | 防跨 App 关联;换签名即变 |
| 随机 UUID | IDFV / IDFA / App Set ID / GAID / Keychain UUID | 系统随机源 | UUID v4 | 不泄露任何信息;可重置 |
| 加密 + 截断 + 模糊 | UTDID、抖音 device_register、拼多多 anti-token | 多源 ID + 随机数 + 时间戳 + 版本号 | 加密串(长度各异) | 抗逆向;实现闭源 |
| 确定性哈希 | UDID(SHA1)、统一社会信用代码 | 硬件标识 / 登记信息 | 定长串 | 可复算;输入可枚举则不能当秘密 |
| 加权校验位 | IMEI(Luhn)、VIN(mod 11)、身份证(MOD 11-2)、USCC(mod 31) | 编码本体 | 1 位校验字符 | 只防手误,不防伪造 |
| 相似度检索 | 指纹加权相似度、Simhash + 汉明距离 | 多维特征 | 分数 / 近邻 | 抗轻微变化;需阈值权衡误判 |
| 物理测量 | SensorID、DrawnApart、时钟偏移 | 传感器 / GPU / 晶振输出 | 增益矩阵 / 时序向量 | 难伪造;依赖硬件公差 |
| 图算法 | OneID / ID-Mapping、卓信 ID 根ID | ID 关系对 | 连通分量 / 聚类 | 能归一;有脏簇与跳变风险 |
| 服务端下发 | QIMEI、卓信 ZID、京东 okuuid、快手 EGID | 客户端上报的多源特征 | 不透明串 | 可找回;依赖服务端与合规 |
21.1 Android 平台官方 ID
21.1.1 ANDROID_ID(SSAID)—— 唯一能读到官方源码的算法
算法在 AOSP 的 SettingsProvider.java 里,方法名 generateSsaidLocked()。逐步还原:
1. 每个 Android 用户(userId)持有一把随机密钥 user_key(16 或 32 字节,十六进制存在 ssaid 表)
2. Mac m = Mac.getInstance("HmacSHA256"); m.init(new SecretKeySpec(keyBytes, ...))
3. 对调用方 APK 的每一个签名证书,依次喂入:
m.update( 4 字节长度前缀 ) // getLengthPrefix(sig)
m.update( sig ) // 证书 DER 字节
4. ssaid = hex(m.doFinal()).substring(0, 16) // 只取前 64 bit → 16 个十六进制字符
5. 以 uid 为键写入 settings_ssaid.xml;之后直接读表,不再重算
/data/system/users/<id>/settings_ssaid.xml,恢复出厂 / 换用户即重建;③ Android 8.0 之前是 Long.toHexString(new SecureRandom().nextLong())——一个纯 64 位随机数,全局唯一且跨 App 共享,这正是 8.0 要把它改成"按签名密钥派生"的原因。
来源:AOSP 源码 aosp-mirror/platform_frameworks_base → SettingsProvider.java(generateSsaidLocked / Mac.getInstance("HmacSHA256") / substring(0,16))🔗;StackOverflow 对同一段源码的逐条解读 🔗;腾讯 WeTest 引用的旧版 SecureRandom.nextLong() 片段 🔗。
21.1.2 App Set ID —— UUID v4,生成在 Play services 内部
Android 官方文档明写返回值"uses version 4 of the universally unique identifier (UUID) format",即 UUID v4(122 位随机 + 版本位 4 + 变体位)。具体生成算法在 Google Play services 内部,未公开(⚠)。两个作用域:SCOPE_APP(每 App 一个)/ SCOPE_DEVELOPER(同 Play 开发者账号共享)。
重置条件(官方列举):该组 App 超过 13 个月未访问 API、该组最后一个 App 被卸载、用户恢复出厂;另外 Play services 从"只支持 app-scope"升级到"支持 developer-scope"时,值会自动重置。
来源:developer.android.com/identity/app-set-id、AppSetIdInfo / AppSetId API 参考 🔗。
21.1.3 GAID / AAID —— 同样是 UUID,且不在 AOSP 里
由 Google Play services(com.google.android.gms:play-services-ads-identifier)返回一个 UUID 形态的不透明串(官方示例 38400000-8cf0-11bd-b23e-10b96e4ef00d)。生成算法不公开(⚠)。用户重置 → Play services 重新生成;Android 12+ 用户可删除 → 所有 App 读到 00000000-0000-0000-0000-000000000000;targetSdk 33+ 未声明 AD_ID 权限也返回全 0。
来源:Android 官方 Advertising ID 文档、AdvertisingIdClient.Info 参考、ppc.land 时间线 🔗。
21.1.4 OAID —— 厂商系统层实现,算法闭源
OAID 由各厂商在系统层实现(HMS Core / MIUI / ColorOS / FuntouchOS / OriginOS / MagicOS…),算法不公开(⚠)。可观察到的事实:不同厂商返回的格式并不一致,因此主流第三方库明确建议"不同厂商的 OAID/AAID 格式不一样,可进行 MD5、SHA1 之类的哈希运算统一"。它的定位是"设备级、由系统维护、用户可重置"的匿名标识。MSA 统一 SDK 闭源,2023 年还曾对 GitHub 上的逆向仓库发起 DMCA 下架(⚠ 有争议)。
来源:github.com/gzu-liyujiang/Android_CN_OAID README 与其 deepwiki、GitHub DMCA 存档 2023-09-21-msa.md、App2China / NextAppMarket 的厂商支持表 🔗。
21.1.5 MediaDrm deviceUniqueId —— 由 DRM 预置流程写入,不是客户端算的
Android 官方对该常量的定义是:"the device unique identifier is established during device provisioning"——即它在设备预置(provisioning)阶段被写入,App 只是读取(getPropertyByteArray(PROPERTY_DEVICE_UNIQUE_ID))。Widevine CDM 的设备标识默认是随机生成并持久化的。因此:不可由 App 推导、不可重置,但也不保证全局唯一(有开发者报告新机撞号)。⚠
来源:developer.android.com/reference/android/media/MediaDrm、NAGRA CONNECT Player SDK 文档(CDM device identifier randomly generated by default)、StackOverflow "Android MediaDrm unique id" 🔗。
21.1.6 IMEI —— 有国际标准的完整算法
IMEI = TAC(8 位) ‖ SNR(6 位) ‖ CD(1 位) // 共 15 位
IMEISV = TAC(8 位) ‖ SNR(6 位) ‖ SVN(2 位) // 共 16 位
CD = Luhn( 前 14 位 ) // ISO/IEC 7812
Luhn 计算(对去掉校验位后的 payload):
从右往左,每第 2 位 ×2;若结果 > 9 则减 9;全部求和得 s
CD = (10 − (s mod 10)) mod 10
TAC 的前 2 位是 Reporting Body Identifier,后 6 位是机型;SNR 由厂商在该机型内分配。校验位不参与网络传输,只用于防止录入错误。
来源:3GPP TS 23.003 Annex B("The Luhn Check Digit (CD) is computed on the 14 most significant digits")🔗、GSMA TS.06 IMEI Allocation and Approval Process(TAC/Serial/Check Digit 字段表)🔗、Wikipedia Luhn algorithm(公式与步骤)🔗。
21.1.7 MAC 地址 —— EUI-48 与随机化
结构是 OUI(前 3 字节,IEEE 分配) + 厂商自定(后 3 字节)。Android 6.0+ 对 App 返回固定假值 02:00:00:00:00:00;系统级随机化按网络(如 SSID)派生、可随网络变化。⚠ 另一类"变"来自故障:NVRAM 损坏时内核会随机生成 MAC(前 3 字节保留、后 3 字节随机),每次重启/重连都变——这是"同一台设备 MAC 频繁变化"的真实成因之一。
来源:腾讯 WeTest《移动终端设备 ID 汇总》中引用的内核代码片段(tuna_mac_addr[3..5] = rand)🔗、Android 官方权限说明 🔗。
21.2 iOS 平台官方 ID
21.2.1 IDFV —— 返回值是 UUID,但"vendor 怎么判定"才是公开的算法
Apple 只说明返回值是 NSUUID(36 字符 UUID),UUID 本身怎么生成未公开(⚠)。但vendor 的判定规则是公开的,这也是 IDFV 唯一"可推演"的部分:
来自 App Store 安装 → vendor 由 App Store 提供的数据决定
非商店安装(企业分发 / 开发中)→ 按 bundle ID 推导:
iOS 6 :取 bundle ID 的前两段 com.example.app1 与 com.example.app2 → 同 vendor
iOS 7+:取除最后一段以外的所有段
单段 bundle ID → 整串都用
另有两个边界:设备重启后、用户首次解锁前可能返回 nil;该 vendor 的全部 App 被删除后重装,值会变。
来源:Apple 官方 identifierForVendor 文档(含 bundle ID 分段表)🔗、StackOverflow 对 iOS 6/7 行为差异的实测记录 🔗。
21.2.2 IDFA / 21.2.3 DeviceCheck
IDFA:ASIdentifierManager.advertisingIdentifier,UUID 格式,用户可重置;ATT 未授权时返回全 0。生成算法未公开(⚠)。DeviceCheck:不是客户端算出的 ID,而是 Apple 服务端为每台设备保存的 2 bit 状态位;客户端用 DCDevice.generateToken() 取一次性 token 交服务端换取状态。算法在 Apple 侧,不公开(⚠)。
来源:Apple 官方 ASIdentifierManager / DeviceCheck 文档 🔗。
21.2.4 UDID(已废弃)—— 少见的"公式完全公开"的 ID
iPhone 4 ~ iPhone X : UDID = SHA1( serial ‖ ECID ‖ wifiMac ‖ bluetoothMac )
更早机型 : UDID = SHA1( serial ‖ IMEI ‖ wifiMac ‖ bluetoothMac )
→ 40 位小写十六进制
2018-09 起(iPhone XS 等)改为直接拼接、不再哈希:
[左侧补零]CHIP "-" [左侧补零]ECID 例:00008020-008D4548007B4F26
注意 ECID 要用十进制且无前导零,MAC 用小写含冒号——这类细节决定哈希值能否复现。
来源:The Apple Wiki / Wikipedia《UDID》、StackOverflow "Derive UDID from iPhone serial"(拼串规则)🔗。
21.2.5 Keychain Access Group —— 不是"算 ID",而是共享通道
机制本身不含算法:App 自生成 UUID v4,写入带同一个 kSecAttrAccessGroup 的 Keychain 条目,同 Team 的 App 都能读。UUID v4 的构造是标准化的:122 位随机数 + 4 位版本号(0100) + 2 位变体(10)。
21.3 国内中台 / 大厂 ID 的算法
21.3.1 QIMEI —— 服务端合成 + 找回,具体算法未公开
官方只披露到"机制"这一层:SDK 采集多种 ID 上报,后台用 ID 关系库 + 山寨库 + 校准算法实时生成/找回终端唯一 ID 并下发。形态 QIMEI(旧,字段 A3)/ QIMEI36(标准 36 位,字段 A153)/ QIMEI16。⚠ 逆向显示实现落在 native 库 libqimei.so 且做了 VM 混淆,社区已有完整还原与 Python 模拟(基于央视频 Android v3.2.2 的 so)。腾讯未公开算法本体。
来源:腾讯灯塔帮助《关于 SDK》、腾讯 MSDK WIKI(Qimei36 说明)、GitHub SkyBlue997/QIMEI(⚠ 第三方逆向,本机网络策略无法直接抓取其页面,仅引用其自述的结论)🔗/⚠。
21.3.2 UTDID —— 阿里把算法写进了官方文档(少见)
官方原文(可直接引用):
生成:"在第一次调用的时候由特定算法生成(AndroidID、IMEI、随机数、时间戳、版本号等等
经过加密、截断、模糊后得到的随机数,基于隐私考虑新版 SDK 不会获取 IMEI)"
存储:"持久化在系统的 Setting 和存储卡以及应用的私有目录,三份值一样"
长度:24 字节(蚂蚁产品手册:utdid 返回 "24 字节的设备唯一标识")
跨 App 机制:每次启动取"应用外的 utdid"与"应用内的 utdid"比对,
使用【生成时间更早】的那个
服务端:DeviceID 由服务端生成,官方原文"生成算法就是 UUID";一个 UTDID ↔ 一个 DeviceID
官方同时承认:"大约有千分之 3 左右重复",并列出重复的三个成因:系统不干净(镜像里自带 UTDID 文件)、一键换机/云同步把文件拷到另一台设备、作弊数据。
来源:阿里云《移动推送的设备标识说明》(help.aliyun.com/zh/document_detail/616675.html)、《详解 DeviceId 与 DeviceToken 及 UTDID 的概念区别与生成关系》(616674.html)、蚂蚁金服/蚂蚁科技产品手册 PDF 🔗。
21.3.3 卓信 ID —— 官方披露"图计算 + 机器学习聚类"
① 根ID(RootID):服务端用 SDK 上传的"设备弱特征"(不具备唯一性/稳定性的特征)
生成"设备模糊标识",仅保存在基础服务提供方,不在生态中流转
② 卓信ID(ZID):由根ID 经"二次匿名化"生成并下发;含【校验码 + 有效期】;
默认有效期 1 个月;同设备不同 App 相同,跨有效期不同
③ 本地ID :App 首次安装启动时由 SDK 生成,是获取 ZID 的凭证
算法核心(官方原文):"服务器根据设备弱特征信号,通过基于图计算的机器学习方法
进行设备聚类,经二次匿名化后生成根ID及卓信ID"
官方并明确:"卓信ID 具备一定的【分裂率和聚合率】"
配套有一个很关键的反滥用设计:群对群转换接口(ConvertZIDGroup,单次 1000~10 万个 ZID,用于把过期 ZID 批量换成最新),并明文禁止单 ID 转换——"不可用于单个个体的卓信ID转换,各CP不得尝试通过变更单一ID来变相获取单一卓信ID的转换能力"。
来源:个推文档中心《卓信 ID 概述》、卓信 ID 官网方案架构页、个推文档中心《服务端接口说明》、中国信通院泰尔终端实验室/个推新闻稿 🔗。
21.3.4 京东 okuuid —— 一条写死的确定性降级链
系统 < Android 10 : UUID = IMEI-MAC (无 IMEI 权限时 = "-MAC")
系统 ≥ Android 10 : 本地已缓存 UUID → 直接用缓存值(IMEI-MAC 或 -MAC)
本地未缓存 → UUID 字段填 Android ID
备选构件:
AndroidId = 设备首次启动时系统随机生成的 64 位数字的十六进制字符串
PseudoId = 读取 ROM 版本号 + 厂商名 + CPU 型号 + 其他硬件信息,组合成 15 位号码
这套链的价值在于"每一步都有确定的降级目标,保证最终一定拿得到一个完整的 UUID",而"与主站打通"(okuuid-jdmall)只是把生成源换成主站同一套。
来源:京东 EMOP 文档中心《接入 Android》(opendoc.jd.com/base/emop/module/UUID/Android.html)🔗。
21.3.5 抖音 device_id / install_id(⚠ 第三方逆向)
接口:POST log.snssdk.com/service/2/device_register/ (另有 log3-misc.amemv.com 等域名)
请求体加密:先用 Gzip 压缩参数,再调 AES 加密(Android 与 iOS 相同)
关键函数被 VM 混淆(设备注册、视频信息等常用接口)
字段坑:carrier、display_name 不是 UTF-8,是 GBK 编码,需转码
Idfa / VendorID 用标准 UUID 算法生成;Openudid 随机生成
返回:{ device_id: 61853858364, install_id: 99375638378, new_user: 1, ... }
device_id 是设备级(由服务端依据提交参数计算/下发),install_id(iid)是每次安装一个。
来源:GitHub shenydowa/deviceid-x-gorgon(⚠ 逆向)、hyb.life/archives/207(⚠ 逆向,定位到 com.ss.android.common.applog.NetUtil)、51CTO《逆向某音短视频 App 之设备激活》(⚠)🔗。
21.3.6 快手 EGID(⚠ 第三方逆向)
走设备注册服务:请求携 productName=KUAISHOU / ts / deviceInfo / sign / rdid
deviceInfo 构造约 119 个字段(EgidNano 结构)
取不到设备号时的降级链:
系统 AndroidID → 无效 → SecureRandom 生成 16 位随机
→ 格式化为 ANDROID_xxxxxxxxxxxxxxxx → 存 SharedPreferences 兜底
来源:GitHub zero199901/kuaishou_public(⚠ 逆向)、快手隐私保护平台与联运 SDK 文档 🔗。
21.3.7 拼多多 anti-token / anti_content(⚠ 第三方逆向)
App 侧:anti-token = DeviceNative.deviceInfo2(context, ts) 生成
实现在 libpdd_secure.so(OLLVM 混淆)
info4 = "2ag" + Base64( AES-128-CBC( 自定义 TLV ) ),约 33 个设备字段
Web 侧:anti_content = 时间戳 + 浏览器/设备指纹 + 操作轨迹 + 动态盐,每次请求重新生成
来源:GitHub mankezhou/Pdd-anti-token、道满 Python《拼多多 anti_content 逆向》(均 ⚠)🔗。
21.3.8 美团 xid / dfpid(⚠ 第三方逆向)
载体:native 库 libmtguard.so;Java 层通过 MTGuard.main(int 编号, Object[] 参数) 分发到不同 native 逻辑
xid :App 第一次运行用【UUID + 时间】加密生成;本地有则读本地,无则向服务端取
dfpid:fetchDfpId() → 本地存储优先(带 interval + lastUpdateTime 有效期)
→ 过期或强制 → postDFPID( encDfpDataForId() ) 向服务端换
→ 服务端返回"折叠后的"设备指纹 ID
采集:在 native 层用反射获取;请求体带签名;修改任一采集字段即生成新的 dfpid(实测)
来源:博客园《美团外卖 APP 设备指纹风控分析》、长亭百川云《外卖 APP 设备指纹风控分析三》、52pojie 同题(均 ⚠ 逆向)🔗。
21.4 推送 / 统计 SDK 的 ID 算法
| SDK | ID | 算法 / 生成方式 | 来源等级 |
|---|---|---|---|
| 极光 JPush | RegistrationID | DeviceID 写 Settings + External Storage;补充规则用 IMEI/MAC/AndroidID 判断"是否老设备",逻辑主要在服务端、可动态调整(官方社区原文) | 🔗 官方社区 |
| 个推 Getui | CID / GID | CID 写 SD 卡以跨卸载存活;GID 为设备级 | 🔗 官方文档 |
| 友盟 Push / U-App | UMID | 官方定义"基于友盟+自己的设备 ID 生成算法,在 App 生命周期保持稳定性和唯一性";具体算法未公开;反作弊模块另用"对 IMEI/Mac/IDFA 低依赖、对重装/跨 App/双开/代理抗干扰强"的设备指纹 | 🔗 官方(实现细节 ⚠) |
| FCM | Registration Token / FID | Token 由 FCM 服务端签发、可轮换;正被 FID(Firebase Installation ID)取代,FID 由客户端生成并持久化 | 🔗 官方 |
| GrowingIO | deviceId | 公开的生成优先级:Android androidId > IMEI > uuid;iOS IDFA > IDFV > uuid;用户拒绝采集时降级为随机 uuid;小程序 用户设置的 id > 随机 uuid | 🔗 官方隐私政策 |
21.5 设备指纹类算法
21.5.1 熵加权相似度匹配(有专利,公式完整公开)
专利 CN106951765A《一种基于浏览器指纹相似度的零权限移动设备识别方法》把"指纹不是查表命中、而是相似度打分 + 阈值判决"写成了公式:
总体相似度 = Σ wᵢ · dᵢ( fp₁, fp₂ ) // wᵢ = 特征 i 的信息熵;dᵢ = 该特征的相似度
各特征的相似度按类型分别定义:
UserAgent → 1 − Levenshtein(UA₁,UA₂) / max(len) 阈值 0.8
Fonts / 语言集合 → Jaccard(A, B) 阈值 0.8
Canvas → 逐像素相同的比例 阈值 0.998
判决:先查完全相同;不命中则算总体相似度,> 0.9 判为同一设备
来源:Google Patents CN106951765A(权利要求与阈值 T1=0.9 / T2=0.8 / T3=0.8 / T4=0.998)🔗。
21.5.2 Simhash(Charikar)—— 海量指纹库的近邻检索算法
1. 对每个特征 i 取 b 位哈希 φᵢ,特征权重 wᵢ
2. 逐位加权投票: W[j] = Σᵢ ( φᵢⱼ == 1 ? +wᵢ : −wᵢ )
3. simhash 第 j 位 = ( W[j] > 0 ? 1 : 0 )
4. 两个指纹的相似度 ≈ 1 − 汉明距离 / b
用途:在百万级指纹库里"找出汉明距离 ≤ h 的所有候选",把 O(N) 全比降为分块查表(PSM / BPHS 等方法)。
来源:Charikar simhash 原始思想、TAMU《Probabilistic Near-Duplicate Detection Using Simhash》(CIKM 2011) 算法 1、Similarity 库文档 🔗。
21.5.3 传感器校准指纹(SensorID)—— 数学过程完全公开
① 采集:<100 组陀螺仪/加速度计/磁力计原始输出(<1 秒,无需权限)
② ADC 值恢复: ΔA = H₀⁻¹ · ΔO // H₀ = 标称增益 × I,先临时替代未知的真实增益 H
③ 增益矩阵估计:对 ΔO 与 ΔA 做最小二乘右除,解出 3×3 增益矩阵 H
④ 指纹定义: GYROID = round(G · 2¹⁶) − round(G₀ · 2¹⁶) // 单位 2⁻¹⁶ dps
⑤ 有效性检查 → 取整/聚类 → DeviceID
实测:iPhone 6S 约 67 bit 熵;Pixel 4/4 XL 约 57 bit;恢复出厂、系统升级、温度与位置变化都不改变。国内同思路专利 CN110990823A 给出六步法(数据采集 → 预处理 → ADC 值恢复 → 增益矩阵估算 → 有效性检查 → DeviceID 生成),实测 5680 台 Android + 4675 台 iOS 100% 提取成功。缓解:Apple 在 iOS 12.2 加随机噪声(CVE-2019-8541)、Google 在 Android 11 把输出取整到标称增益的整数倍。
来源:IEEE S&P 2019《SensorID》论文与演讲 PPT(含 iPhone XS 的 GyroID / MagID 实际矩阵)、TIFS 2020《Factory Calibration Fingerprinting of Sensors》、专利 CN110990823A 🔗。
21.5.4 Canvas 指纹 —— 算法只有四步
1. 建离屏 canvas,取 getContext('2d')
2. 画:设字体/颜色 → fillText( 文字 + emoji ) + fillRect + 叠加半透明填充(压测抗锯齿)
3. 读回:toDataURL('image/png') → Base64 PNG
或 getImageData() → 原始 RGBA 字节(更贴近硬件、绕过编码器)
4. 哈希:MD5 / SHA-256(早期也有用 PNG IDAT 块的 CRC / Adler-32)
像素差异来自三层、且都不在 JS 可控范围内:① 字体栅格化器(CoreText / DirectWrite / FreeType 的抗锯齿与子像素策略不同)② GPU 与驱动(浮点混合结果不同)③ 色彩配置(向显示器 profile 转换)。Mowery & Shacham 2012 实测:同一段 Arial 文本 300 个样本得到 50 种不同位图;294 个浏览器实例得到 116 个不同指纹,仅文本部分约 5.73 bit 熵。现代实现把"文字图"和"几何图(globalCompositeOperation='multiply' 的 GPU 混合)"分成两张分别哈希——因为文字图更不稳定,避免它污染更稳的几何信号。
来源:Mowery & Shacham《Pixel Perfect: Fingerprinting Canvas in HTML5》(2012)、crawlex《Canvas fingerprinting》深度文、Grokipedia 词条 🔗。
21.5.5 GPU 芯片级指纹(DrawnApart)与时钟偏移
DrawnApart:用 WebGL 对同一 GPU 内不同执行单元下发短任务并测时,利用制造公差造成的速度差异,把时序轨迹喂给深度模型映射成嵌入向量——把 GPU 指纹从"型号级"提升到"单颗芯片级",中位追踪时长 +67%;WebGPU 版(LockedApart)快 310×、准确率高 1.8×。
时钟偏移:晶振制造公差 → ppm 级固有偏移;用 TCP/ICMP 时间戳做线性回归(凸包算法)估出 skew,实测 100 台设备偏移落在 67 ~ −499 ppm。
21.6 网络层指纹的算法
21.6.1 JA3 / JA4(TLS 客户端指纹)
JA3 = MD5( TLSVersion "," Ciphers "," Extensions "," EllipticCurves "," ECPointFormats )
// 各列表内部用 "-" 连接;先剔除 GREASE 值(RFC 8701)
例:771,4866-4867-4865-49196-49200,0-23-65281-10-11-35-16-5-13,29-23-24,0
→ 9b0a1e74c72f9ab20e6379dffde7a5de
JA4 = a_b_c
a = 可读前缀:协议(t/q) + 版本(13/12) + SNI(d/i) + 密码数(2 位) + 扩展数(2 位) + 首个 ALPN
例 t13d1516h2
b = 【排序后】密码套件列表的 SHA-256 截断 12 字符
c = 【排序后】扩展(去掉 SNI/ALPN)+ 签名算法的 SHA-256 截断 12 字符
JA4 相对 JA3 的三点改进:排序→抗扩展顺序随机化(Chrome 已随机化)、SHA-256 截断→抗 MD5 碰撞、支持 QUIC(HTTP/3 的 TLS 装在 UDP 里)。
21.6.2 p0f / JA4T(TCP/IP 栈指纹)
p0f 签名语法: ver : ittl : olen : mss : wsize,scale : olayout : quirks : pclass
例(Linux 3.11+): 4:64:0:*:mss*10,6:mss,sok,ts,nop,ws:df,id+:0
ittl=推断初始 TTL(64 Linux/macOS、128 Windows、255 网络设备)
olayout = TCP 选项出现顺序(mss / sok / ts / nop / ws / eol+n)
21.6.3 IPv6 SLAAC:RFC 7217 的 IID 生成公式
RID = F( Prefix, Net_Iface, Network_ID, DAD_Counter, secret_key )
F() :抗外部计算、不可逆的 PRF;可用"对参数拼接做 SHA-256"实现(MD5 明确不可接受)
secret_key :≥128 bit,系统安装时随机初始化,不对外
Network_ID :可选(如所连 Wi-Fi 的 SSID)
IID = 取 RID 的最低有效若干位(单播地址通常取 64 位)
效果:同一网络内稳定、跨网络不可预测(前缀与 Network_ID 变化 → IID 变化)。而 RFC 8981 的临时地址是另一条路线:直接随机化 IID,并按 lifetime(默认约 24 小时)轮换。
21.6.4 DHCPv6 DUID 的四种格式
DUID-LLT = 类型(2B)=1 ‖ 硬件类型(2B) ‖ 时间戳(4B) ‖ 链路层地址
DUID-EN = 类型(2B)=2 ‖ 企业号(4B) ‖ 厂商自定义数据
DUID-LL = 类型(2B)=3 ‖ 硬件类型(2B) ‖ 链路层地址
DUID-UUID = 类型(2B)=4 ‖ 16 字节 UUID (RFC 6355)
21.7 法定 / 行业标识的校验算法
21.7.1 统一社会信用代码(GB 32100-2015)—— 双层校验
18 位 = 登记管理部门(1) ‖ 机构类别(1) ‖ 行政区划(6) ‖ 主体标识码(9) ‖ 校验码(1)
字符集 31 个: 0123456789ABCDEFGHJKLMNPQRTUWXY // 去掉易混的 I O S V Z
加权因子 Wᵢ = 3^(i−1) mod 31 = [1,3,9,27,19,26,16,17,20,29,25,13,8,24,10,30,28]
校验码 C18 = CHARSET[ (31 − ( Σ(Cᵢ×Wᵢ) mod 31 )) mod 31 ]
内层:第 9~16 位(组织机构代码本体)按 GB 11714 算第 17 位
(权重 3/7/9/10/5/8/4/2、mod 11、校验值 10 记 X)
例:前 17 位 91350100M000100Y4 → 第 18 位为 3,完整码 91350100M000100Y43。
21.7.2 公民身份号码(GB 11643-1999 / ISO 7064 MOD 11-2)
加权因子 Wᵢ = 2^(i−1) mod 11 → [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]
S = Σ( aᵢ × Wᵢ ) (i 从右往左,1..17)
余数 r = S mod 11
校验码 = (12 − r) mod 11,等于 10 时写 X
r 的映射表: r=0..10 → 1, 0, X, 9, 8, 7, 6, 5, 4, 3, 2
例:本体码 11010519491231002 → S=167 → r=2 → 校验码 X。
21.7.3 VIN 车辆识别代号(ISO 3779 / GB 16735-2019)
字母转数字: A=1 B=2 C=3 D=4 E=5 F=6 G=7 H=8
J=1 K=2 L=3 M=4 N=5 P=7 R=9
S=2 T=3 U=4 V=5 W=6 X=7 Y=8 Z=9 // 不使用 I O Q
加权因子: [8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2] // 第 9 位(校验位自身)权重 0
第 9 位 = ( Σ 值×权重 ) mod 11,余数 10 记 X
21.7.4 OneID / ID-Mapping —— 图算法
1. 顶点:每个可标识字段的值(哈希成 long 作 VertexId)
2. 边 :同一条记录里的字段两两相连(无向)
3. 连通分量:Spark GraphX connectedComponents(),一个连通子图 = 一个自然人
4. OneID:MD5( 连通子图的代表 id ),或用雪花算法发号
5. 稳定性规则:若簇内任一顶点已有历史 OneID,则【沿用历史值】,不重新生成
6. 脏簇熔断:簇内节点数 > 5000 判为公共设备/黑产造成的脏簇,不分配 OneID,转人工审核
7. 流式增量:并查集 union by size;【锚点(强 ID)所在簇永远作 root】;
且不做路径压缩 —— 否则 OneID 会跳变
21.7.5 微信的 openid / unionid —— 官方给了公式
微信用户 + 公众号 AppID = openid // 同一用户在不同 App 下 openid 不同
微信用户 + 开放平台账号 = unionid // 同一开放平台下所有应用 unionid 相同
21.8 一句话总结
① 客户端侧——多源采集 + 确定性降级链(京东 okuuid)/ 带密钥哈希(SSAID)/ 加密截断(UTDID、抖音);
② 服务端侧——归一与找回:图算法聚类(卓信根ID、OneID)、映射表与找回算法(QIMEI)、UUID 映射(阿里 DeviceID);
③ 校验侧——加权校验位(IMEI/VIN/身份证/USCC)、相似度阈值(指纹加权相似度、Simhash)、有效性检查(SensorID)。
这也解释了为什么"客户端单点自算跨 App 唯一 ID"做不到:①能保证的只是"同一台设备上算出来的东西一致",而"跨设备/跨卸载/跨开发商"的收敛必须靠 ②,可靠性必须靠 ③。
二十一、逆向分析与开源实现实证
这些来源一律标注 ⚠:结论来自第三方逆向,未经厂商确认,实现细节随版本变化, 不能作为合规或法务依据;但用来印证架构判断,是官方材料给不了的一手材料。
21.1 逆向材料反复验证的一件事:多数"设备唯一 ID"不是本地算出来的
这是本节最重要的发现,也是对第九节推荐架构(本地自生成 UUID 为主键 + 平台 ID 作锚点 + 服务端合并映射) 最硬的旁证:越是跨 App、越是被风控依赖的 ID,越倾向由服务端下发,而不是客户端本地生成。
| ID | 产生位置 | 逆向观察到的机制 | 来源 |
|---|---|---|---|
| 腾讯 QIMEI | 服务端下发 | Java 层 com.tencent.qimei 采集指纹 → CMD.REGISTER 上报 → 服务端下发含 q16/q36 的加密 body,本地只做加密存储 |
⚠[173] |
| 快手 EGID | 服务端下发 | 第一步 POST /rest/infra/gdfp/report/android 上报加密 deviceInfo,服务器返回 egid(64 字节 hex,形如 DFP51921CA87…) |
⚠[164] |
| 快手 did | 本地随机生成 | 客户端随机生成,格式 ANDROID_ + 16 位 hex(deviceInfo 的 #66 字段)—— 与 EGID 并存,各司其职 |
⚠[164] |
| 抖音 device_id / install_id | 服务端下发 | device_register 由 libEncryptor.so(TTEncrypt 5.5.0)生成二进制 payload 后换取,请求体 content-type: application/octet-stream;tt-data=a |
⚠[167][168] |
| 阿里 mtop eeid | 服务端下发 | 首次启动发三次请求,返回的 data.dt 携带风险特征、算法变化指令与设备 id(eeid) |
⚠[174] |
| Apple DeviceCheck token | Apple 服务端(SE 参与) | 系统守护进程 devicecheckd 经 XPC 生成;2 bit 状态存在 Apple 服务器,与硬件强绑定,抹机也难清除 |
⚠[176] |
21.2 风控 SDK 的算法实现(逆向实证)
官方文档只会说"使用专有加密算法",逆向材料给出了具体是什么:
| 对象 | 逆向出的算法 / 机制 | 来源 |
|---|---|---|
| 某盾设备指纹 | 抓包为二进制格式;HOOK RegisterNatives 定位到 SO 分发函数(偏移 0x82f14,被调三百余次);面对 OLLVM + VMP,用自研 trace 导出约 8.3G / 8000 万行指令流定位加密函数;结论:魔改 AES-128 CBC —— 密钥扩展第一组被改(引入 replace_key 查表与 g_table 常量),其余组沿用标准规则;32 字节 KEY+IV 与固定常量异或后上报(动态密钥上报,抬高攻击成本) |
⚠[157] |
| 某知名风控 SDK | 先拉服务端配置(采集开关 risk_apps、sensitive.*),再按配置从 Java + Native 双层采集组成 dict;上传前用注解把每个 key 换成 a1/a2 等无意义名,最后加密上报、服务端生成指纹。Native 层读 /proc/self/maps 查 frida、用 /proc/interrupts 里的 goldfish/qemu 关键字检测虚拟机;作者用 obpo-plugin 对抗 ollvm |
⚠[177] |
| 某 SDK 注册风控 | 以"必须携带后台下发的设备 id"为注册门槛(下发协议请求不成功就无法继续注册),逻辑在 libdu.so;明文是一段混淆键名的 JSON 设备指纹(ubF 为设备 id,另有机型 / 网络 / adb._tcp / WIFI / IP 等);加密为 xor(zlib(设备指纹)),每次请求 xor 密钥不同但对同一请求固定,字段按设备指纹某数据后三位 /100 选择换位形式 |
⚠[160] |
| 某 App 设备风控 | OKHttp intercept 注入 v-mode(是否 VPN,走 VPN 注册会被拦)、KEY1(疑设备 id)、KEY2(疑风控数据);native siua(偏移 0x8da04)返回值经 do_compress_and_encrypt,base64 前以 78da 开头即 zlib 压缩的环境数据;用 /proc/self/attr/prev(正常为 init,Magisk 接管后为 zygote)与 /proc/self/mountinfo 检测 Magisk。作者的绕过尝试仍被封号 —— 说明设备已被标记或另有上报口径 |
⚠[158] |
| 某宝 mtop 风控 SDK(iOS) | mtop 是移动端↔服务器 API 网关;风险字段名为 r_数字_数字,经 svc 指令调用,扫描越狱特征(Cydia / Sileo / MobileSubstrate)与改机工具(iGrimace / NZT / TouchSprite);采集分 OC 方法(UTDevice、utdid)、C 方法与自定义方法(llc_do_syscall);核心逻辑经 VMP 保护,上报数据单字段 → 分段 → 整体多层加密 |
⚠[174] |
| 某 iOS 风控设备指纹 | 核心加解密放进安全虚拟机(指令解释执行,无法反编译还原)+ 运行时完整性校验 / 调试器监测 / 越狱检测 / 注入与 hook 检测;作者从内存截取加密前字段(K1/K10/K11… 含 MAC、机型、WiFi、电量、系统版本),还原出 get_network_info(代理检测)、_UIDevice_stee_isJailbreak_1(越狱检测)等对应关系,最终在内存中篡改组合好的 key:value,把 constId 改成新值、风险位全置否,攻击成功 |
⚠[162] |
21.3 大厂设备标识的注册链路(逆向实证)
| ID / 签名 | 逆向出的链路 | 来源 |
|---|---|---|
| 腾讯 QIMEI | native 层 libqimei36.so(Java 桥 com.tencent.qimei.uin.U,注册 17 个 JNI 方法)只负责密文读写与指纹采集;串结构 [版本字节=3][4 字节大端值][主体];加密为 XTEA(0x9E3779B9 系列常量)+ RSA/ECB/PKCS1Padding 公钥加密 32 字节;上报字段 crypt/params/key/nonce/time/extra/sign(短格式 cpt/pms/ky/nn/tm/ext/sn);核心函数 qimei_core_generate 被 OLLVM 控制流平坦化(111KB、3653 个基本块,F5 反编译失效);敏感字符串以"长度 + 种子 + 步长 83 滚动异或"混淆 |
⚠[173] |
| 快手 did / EGID 注册 | 五步链路:① POST /rest/infra/gdfp/report/android 上报加密 deviceInfo → 返回 egid;② POST /rest/n/log/client/collect 上报日志事件;③–⑤ 走 /antispam/sdk、/antispam/pluginManage、/antispam/dataReport,全部返回 result:1 才算注册成功。deviceInfo 生成链路:80+ 字段 → Protobuf 序列化 → AES-128-CBC(PKCS7)→ Base64 → URL 编码。判定 did/egid 是否有效的方法是用业务接口能否拉到数据 |
⚠[164] |
| 快手 sig3(纯算) | App 走 QUIC,需先 hook cronetConfig 把 enable_quic 降级;Java 层 hook HashMap.put 捕获 __NS_sig3,入口 com.kuaishou.android.security.internal.crypto.e.c,经统一分发 doCommandNative(命令字 0335)进入 libkwsgmain.so;用 IDA patch + 自写 TraceClean 插件配合 unidbg 从结果倒推调用链。结论:sig3 = HMAC-SHA256 → 白盒 AES-128(DFA 差分故障攻击提取密钥)→ CRC32,再打包成 6-int SignatureBlock 并异或混淆 |
⚠[175] |
| 快手 sig(早期) | POST /rest/n/user/profile/v2 的 sig 为 32 位,分析为 MD5:把 URL 参数与表单参数合并、按 key 排序、以 key=value 拼接后计算。另一份记录称签名由 CPU.getClock()(libcore.so 中的 native 方法)计算 —— 两代方案并存,印证"算法会演进" |
⚠[170][171] |
| TikTok 签名头 | 单一函数 generate_headers(url, method, body, cookie, ts, device) 为所有 API 生成签名头(X-Gorgon / X-Khronos / X-Ladon / X-Argus / X-SS-STUB 等共 28 个头);设备注册走 device/Libs/unidbg.jar 加载 libEncryptor.so、以 TTEncrypt 5.5.0 生成二进制 payload,POST 到 log-va.tiktokv.com/service/2/device_register |
⚠[167][168] |
| 京东 Sign | 直接运行卡死闪退 → 判定有 frida 检测(默认端口 27042),改用魔改 strongR-frida-android 换端口成功;hook BitmapkitUtils.getSignFromJni 拿到入参与结果(st=…&sign=…&sv=122);再用 Unidbg 黑盒补环境(Context / unZip / PKCS7);算法定位到 sub_126AC(Base64)与 sub_227C(Base64 再 MD5),用 HookZz 固定 lrand48 控制 sv |
⚠[163] |
21.4 iOS 侧:DeviceCheck 与 UDID —— 苹果把"设备身份"收到了自己手里
第六节讲过 DeviceCheck 的能力(2 bit 状态、抹机不清除),这份逆向材料补上了机制与攻防实况:
| 环节 | 逆向出的细节 | 来源 |
|---|---|---|
| 状态 | 每个「设备-App 组合」在 Apple 服务器保存 2 bit(bit0/bit1,00/01/10/11 四种状态),与硬件强绑定;重置 IDFA、卸载重装乃至抹机恢复出厂都难以清除 | ⚠[176] |
| Token 生成 | 系统守护进程 devicecheckd 经 XPC 生成:先在 Secure Enclave 内创建临时 P-256 密钥(aks_ref_key_create),与苹果服务器公钥(fallback_server_pubkey)做 ECDH,再经 HKDF(SHA256, L=44) 派生 AES-256-GCM 的 key/IV,加密「临时公钥 + 时间戳 + 激活证书 + AppID」,封装为 version=2 的 Base64 Token | ⚠[176] |
| 不可伪造性 | SE 私钥不可导出;服务端用苹果根证书链验签 attestation 并做硬件 ID 一致性检查 | ⚠[176] |
| 攻防实况 | 黑灰产侧:白名单证书库"借尸还魂"、真机群控、RPC 签名节点;防守侧:服务端 Query/Update API、2 bit 持久封禁、时间戳/频率风控。作者在 iPhone 14 / iOS 16.4.1 / Dopamine 越狱环境用 Frida + IDA 实测(含 ECC signature verification failed 报错) | ⚠[176] |
| UDID(历史) | 早年可经 Safari + .mobileconfig 描述文件取得真实 UDID/IMEI(安装描述文件后向回调地址 POST XML plist;需 application/x-apple-aspen-config 与 301 重定向)。该机制已被 Apple 废弃,仅具历史参考价值 | ⚠[172] |
21.5 对抗侧:"一键新机"的技术栈
一份看雪系列文章系统梳理了在 Root 环境下不注入、不修改目标 App 任何代码,却实现"一键新机"的思路, 把 Android 设备指纹的产生位置归为五类,并逐一给出对抗手段:
| 指纹产生位置 | 对抗手段(逆向观察) |
|---|---|
system_server 系统服务 | 动态代理 ServiceManager 替换系统服务;hook SettingsProvider.call 批量改 Android ID;hook packageManager 隐藏包名 |
init 进程(DRM,走 native binder) | 最终落在 /vendor/lib64/libwvhidl.so,属 native 层 |
内核 boot_id | 用 Apatch 的 KPM 模块经自定义 syscall mock sysctl_bootid |
| 小米安全中心(OAID/VAID/AAID) | 厂商侧标识,需单独处理 |
getprop 环境属性 | 系统属性层 |
工程化手段:用 Magisk 模块注入 lsplant 自实现 Xposed;以共享内存 + InMemoryDexClassLoader 分发 dex,
并用 obfuscation.cpp 做内存混淆。来源:⚠[159]。
21.6 开源实现:OAID 与替代方案
第四节把 OAID 列为"零权限、跨开发商"的少数可行方案之一,但指出其生成算法未公开。开源实现补上了这一环:
| 项目 | 要点 | 来源 |
|---|---|---|
| Android_CN_OAID ≈2874 ★ / 468 fork,持续维护 |
Java 实现的开源 OAID 方案(Mulan PSL v2),可作为 MSA 统一 SDK(miit_mdid_xxx.aar)的替代品,主要面向无资格使用 MSA SDK 的个人开发者;统一封装各厂商 OAID 与海外 AAID,并附 IMEI/MEID、AndroidID、WidevineID、PseudoID、GUID、画布指纹等常见标识的获取方法;给出 Gradle 依赖、混淆规则与厂商支持表(华为/荣耀/小米/vivo/OPPO/三星/联想等)。作者说明基于北京数字联盟公开代码并结合厂商(含未公开)接口加工,并提到 2tu/msa 曾因版权被 MSA 举报(DMCA 2023-09-21) |
⚠[165] |
| Get_Oaid_CNAdid | 北京数字联盟开源,整合各厂商获取 OAID 的原生方法;说明 OAID 是移动安全联盟(中国信通院下属电信终端产业协会的下属联盟)联合终端厂商推出的团体标准,并援引《标准化法》第二十二条主张标准应公开、不得用于排除或限制市场竞争;列出各厂商支持的系统版本(如小米 MIUI 10.2+、华为全版本),并明确 OAID 的重置特性:用户可手动重置、恢复出厂会重置、可定期重置,关闭后返回 NO,会随时间变化,不能作为稳定索引 key |
⚠[166] |
21.7 本节对前二十节结论的修正与加强
| 前二十节的结论 | 逆向材料给出的补充 / 修正 |
|---|---|
| 第十二节:QIMEI 算法本体未公开(标 ⚠ 存疑) | 补充:已有第三方逆向给出串结构([版本字节=3][4 字节大端值][主体])、加密方案(XTEA + RSA/ECB/PKCS1Padding)、上报字段名与 OLLVM 保护情况;但"服务端下发"这一条是关键修正 —— 报告原先侧重"客户端如何生成 QIMEI",实际客户端只做采集与密文存储 |
| 第十三节:推送 SDK 的唯一 ID 对外应用级、内部设备级 | 加强:逆向显示各家在 native 层用 Protobuf / 自定义加密 / 白盒 AES 组装上报体,正是"对外不暴露设备级、内部按设备级处理"的实现方式 |
| 第十九节:单特征不唯一,熵可加、组合才唯一 | 加强:快手 EGID 的 deviceInfo 含 80+ 字段、某风控 SDK 采集 Java+Native 双层字段 —— 与"组合才唯一"完全吻合;而"一键新机"正是逐项对抗这些字段 |
| 第二十节:跨客户端唯一 ID 从不是单算法,而是三类算法组合 | 加强:快手 sig3 = HMAC-SHA256 + 白盒 AES + CRC32 三段组合;某盾 = 两轮 XOR + 魔改 AES-128 CBC;QIMEI = XTEA + RSA 混合 —— 印证"组合"而非"单算法" |
| 第九节:本地自生成 UUID 为主键 + 平台 ID 作锚点 + 服务端合并映射 | 加强(本节最强的一条):QIMEI、快手 EGID、抖音 device_id、阿里 eeid、Apple DeviceCheck 全部由服务端下发;快手 did 这类本地生成的 ID 只作辅助。厂商自己都不把"本地算出的 ID"当跨 App 锚点 |
二十二、来源清单
用法:点击正文中的蓝色 [编号] 可跳到下方对应来源(该条会高亮);点来源条目末尾的 ↩ 可返回刚才的引用位置。
- 🔗 Apple — identifierForVendor(UIDevice):developer.apple.com/documentation/uikit/uidevice/identifierforvendor ↩
- 🔗 Apple — DeviceCheck(DCDevice,2 bit/设备):developer.apple.com/documentation/devicecheck ↩
- 🔗 DevelopersIO — iOS 可获取标识符 vs Android SSAID 对比表:dev.classmethod.jp/en/articles/ios-device-identifiers-vs-android-ssaid ↩
- 🔗 Android 官方 — Identify developer-owned apps(App set ID 指南):developer.android.com/identity/app-set-id ↩
- 🔗 Android API 参考 — AppSetId(SCOPE_APP / SCOPE_DEVELOPER):developer.android.com/…/appsetid/AppSetId ↩
- 🔗 Android 官方 — AdvertisingIdClient.Info(AD_ID 权限、全零规则):developers.google.com/android/reference/…/AdvertisingIdClient.Info ↩
- 🔗 Android 官方 — 唯一标识符最佳做法:developer.android.com/identity/user-data-ids ↩
- 🔗 Google — Advertising 政策(重置/删除广告 ID):policies.google.com/technologies/ads ↩
- 🔗 PTKD — Android Advertising ID vs App Set ID 对比:ptkd.com/journal/android-advertising-id-app-set-id-privacy ↩
- 🔗 Android API 参考 — MediaDrm(PROPERTY_DEVICE_UNIQUE_ID):developer.android.com/reference/android/media/MediaDrm ↩
- 🔗 Ping Identity — React Native 设备标识(跨 App 共享策略):developer.pingidentity.com/…/react-native-device-ids.html ↩
- 🔗 Alejandro Cordón — Unique Identifiers in Android and iOS(ANDROID_ID 三元组):alejandrocordon.com/blog/2025/01/18/unique-identifiers-android-ios ↩
- 🔗 MSA 移动安全联盟 — 补充设备标识体系隐私政策(UDID/OAID/VAID/AAID):msa-alliance.cn/col.jsp?id=122 ↩
- 🔗 阿里云开发者 — Android 平台 IMEI 弃用后如何集成 OAID SDK:developer.aliyun.com/article/1063022 ↩
- 🔗 腾讯云开发者 — OAID 集成教程(四类标识 + 同开发者判定):cloud.tencent.com/developer/article/2123802 ↩
- 🔗 ppc.land — Explaining mobile advertising ID(时间线 + Privacy Sandbox 退役):ppc.land/mobile-advertising-id ↩
- 🔗 AppsFlyer — Device identifiers(IDFA/IDFV/GAID/OAID 用途):support.appsflyer.com/…/4408847686161-Device-identifiers ↩
- 🔗 Docs — Apphud Device Identifiers(IDFA 需 ATT / IDFV 自动):docs.apphud.com/docs/device-identifiers ↩
- 🔗 shieldlabs — Persistent Device IDs(迁移顺序 / 存储层):shieldlabs.ai/blog/persistent-device-id ↩
- 🔗 pub.dev — device_id_manager(Keychain / MediaDrm 实现):pub.dev/packages/device_id_manager ↩
- 🔗 OneSpan — Obtain the device fingerprint(AccessGroup 跨 App 共享):docs.onespan.com/…/obtain-the-device-fingerprint-5-5-0 ↩
- 🔗 Firebase 官方 — Manage Firebase installations(FID 特性与重置):firebase.google.com/docs/projects/manage-installations ↩
- 🔗 StackOverflow — Android 10 IMEI 替代方案(MediaDrm 实践):stackoverflow.com/questions/58103580 ↩
- 🔗 GitHub — swift-security keychain-sharing(Access Group 机制/Team 隔离):github.com/ivan-magda/swift-security-skill ↩
- 🔗 bidlogic — What's after the Android Privacy Sandbox:bidlogic.io/2026/02/27/whats-after-the-android-privacy-sandbox… ↩
- 🔗 arXiv 2506.22639 — Fingerprinting SDKs for Mobile Apps:arxiv.org/pdf/2506.22639 ↩
- 🔗 Branch — Advertising Identifiers for Attribution(IDFV/OAID 用途):help.branch.io/docs/advertising-identifiers-for-attribution ↩
- 🔗 灵犀游戏 — 第三方 SDK 收集使用信息说明(国内实证清单):agreement.lingxigames.com/…/agreement.html ↩
- 🔗 祖龙娱乐 — 第三方信息共享清单(国内实证清单):res.zulong.com/zl_agreement/agreement_SDK.html ↩
- 🔗 灯塔帮助 — 关于 SDK(QIMEI 官方定义:ID 关系库/山寨库/校准算法):beacon-help.gitbook.io/beacon-help/faq/guan-yu-sdk ↩
- 🔗 腾讯 MSDK WIKI — Android 数据上报(Qimei36 说明、appKey、24h 刷新):wiki.ssl.msdk.qq.com/Android/stat.html ↩
- 🔗 腾讯 MSDK WIKI — iOS 数据上报(Qimei36、接入前置条件):wiki.ssl.msdk.qq.com/IOS/stat.html ↩
- 🔗 腾讯隐私保护平台 — QIMEI SDK 个人信息保护规则(采集字段与权限,2025-09):privacy.qq.com/document/preview/91754d6dd7824e3689f17782c580e06e ↩
- 🔗 腾讯 WeTest — 移动终端设备 ID 汇总简介(QIMEI v3.0、服务端生成+找回):wetest.qq.com/labs/116 ↩
- 🔗 腾讯云 — 腾讯云 Anti-Cheat Expert (ACE) 游戏安全(反外挂/设备识别):cloud.tencent.com/developer/article/2660674 ↩
- 🔗 腾讯云 — 设备安全 TDS(可信设备标识 + 设备指纹/风险识别):cloud.tencent.com/product/tds ↩
- 🔗 腾讯云 — 设备安全 查询设备标识 DescribeTrustedID(DeviceToken → 可信 ID):cloud.tencent.com/document/product/1628/81017 ↩
- 🔗 极光社区 — registrationID 详细定义/变化原因/同 ID 异常:community.jiguang.cn/article/111901 ↩
- 🔗 极光社区 — 极光推送的设备唯一性标识 RegistrationID(DeviceID 存储与 IDFA 选项):community.jiguang.cn/article/36680 ↩
- 🔗 友盟 — 消息推送基础概念(Device Token 44/64 位):developer.umeng.com/docs/67966/detail/98598 ↩
- 🔗 友盟 — 推送 SDK 集成(同一设备不同应用 deviceToken 不一样):developer.umeng.com/docs/67966/detail/206987 ↩
- 🔗 阿里云 — 移动推送设备标识说明(UTDID / DeviceID / Token):help.aliyun.com/zh/document_detail/616675.html ↩
- 🔗 阿里云 mPaaS — utdid 设备标识概念及唯一性说明("不能保证绝对唯一"):help.aliyun.com/document_detail/68178.html ↩
- 🔗 个推文档中心 — Android 常见问题(CID 定义与变化条件):docs.getui.com/getui/question/android/ ↩
- 🔗 个推文档中心 — 产品简介(CID 概念):docs.getui.com/getui/ ↩
- 🔗 小米澎湃OS 开发者平台 — 推送常见问题(regID 生成/变化/失效):dev.mi.com/xiaomihyperos/documentation/detail?pId=1545 ↩
- 🔗 腾讯云 — 移动推送 推送接口(token 单推/批量推):cloud.tencent.com/document/product/548/39064 ↩
- 🔗 itsectr — FCM Registration Token 说明(生成/失效条件):itsectr.com/en/knowledge/push-notifications/registration-token ↩
- 🔗 firerun — FCM 以 FID 取代 Registration Token(Admin SDK 变更):firerun.io/blog/firebase-fcm-token-fid-deprecation-2026 ↩
- 🔗 Android 官方 — 唯一标识符最佳做法(中文,FID/GUID/应用组 ID 建议):developer.android.com/identity/user-data-ids?hl=zh-cn ↩
- 以下为第十六节「细分行业全景」新增来源
- 🔗 Adjust — S2S 归因检查表(MMP 自建永久 UUID 存 Keychain、广告 ID 可重置、iOS 约 15% 用户开 LAT):dev.adjust.com/zh/api/s2s-api/attribution-checklist ↩
- 🔗 Adjust — MMP 买方指南(设备 ID 成稀缺数据、跨设备/跨渠道归因):adjust.com/zh/resources/guides/mmp-buyers-guide ↩
- 🔗 Adjust — 安卓 SDK 集成(gps_adid、AD_ID 权限、Install Referrer):dev.adjust.com/zh/sdk/android ↩
- 🔗 FTC PrivacyCon 2022 — 无 Cookie 世界的追踪架构对比(UID2.0 / RampID / SWAN):ftc.gov/…/PrivacyCon-2022-Parham-Toward-Greater-Consumer-Surveillance…pdf ↩
- 🔗 W3C — Mitigating Browser Fingerprinting in Web Specifications(指纹跨源识别与 cookie-like 追踪):w3.org/TR/2025/NOTE-fingerprinting-guidance-20250320 ↩
- 🔗 AttriTouch — 短剧/电商/内容出海自建归因实战(设备 ID 归因 + 链接归因 + 一方数据):attritouch.com/blog/self-built-attribution ↩
- 🔗 顶象 — 设备指纹文档中心(hardId/token、AppId/AppSecret、采集字段与权限):dingxiang-inc.com/docs/detail/const-id ↩
- 🔗 数美科技 — 设备指纹 / 设备 ID / 风险设备识别产品页:ishumei.com/new/m/product/tw/sdk ↩
- 🔗 华为云 — 顶象业务安全解决方案实践(金融/电商/航司/网约车案例,设备指纹+决策引擎):support.huaweicloud.com/dxbss-sag(顶象业务安全解决方案实践) ↩
- 🔗 看雪社区 — 设备指纹采集字段剖析(MediaDrm.getPropertyByteArray、boot_id、应用安装列表):bbs.kanxue.com/thread-280869.htm ↩
- 🔗 工银亚洲/华商银行 — 通用 U 盾(数字证书确保身份认证唯一性,一设备一盾):v.icbc.com.cn/…/udgrkh.pdf ↩
- 🔗 证券时报/杭商网 — 银行取消手机盾业务将成趋势(手机盾=数字证书强认证,一客户限一设备):m.tthmx.com/shangye/146460.html ↩
- 🔗 微信开放文档 — 基本概念介绍(AppID / openid / UnionID 定义):developers.weixin.qq.com/doc/oplatform/…/terminology_introduce ↩
- 🔗 微信开放文档 — UnionID 机制介绍(同开放平台账号下跨应用唯一):developers.weixin.qq.com/minigame/dev/guide/open-ability/union-id.html ↩
- 🔗 人人都是产品经理 — 微信账户体系科普(OpenId / UnionId / wxopenid):woshipm.com/pd/3707175.html ↩
- 🔗 数据人社区 — 阿里/网易/美团/58 用户画像 ID 体系建设(OneData:OneModel/OneID/OneService):shujurenclub.com/…/ID-ti-xi-jian-she.html ↩
- 🔗 GrowingIO — OneID 融合产品(全域实时可配置的身份整合):growingio.com/news/349 ↩
- 🔗 龙石数据 — 数据中台 OneID / ID-Mapping(多种 ID 映射到统一 ID):longshidata.com/blog/c/c2023062701.html ↩
- 🔗 界面新闻 — 腾讯视频登录设备数限制与封号(防黑灰产账号共享):jiemian.com/article/13442953.html ↩
- 🔗 21 世纪经济报道 — 视频平台限制账号共享(Netflix 用 IP + 设备 ID + 账户活动判断):m.21jingji.com/article/20230217/… ↩
- 🔗 工信部 — 工业互联网标识解析体系“贯通”行动计划(2024-2026)解读(标识编码=身份证/门牌号):miit.gov.cn/zwgk/zcjd/art/2024/art_067bcc…html ↩
- 🔗 工信部 — 《工业互联网标识管理办法》解读(主流标识体系 Handle/OID/Ecode/VAA;标识服务机构五类):ythxxfb.miit.gov.cn/…/art_19515a7965c846f188f3bdae81463706.html ↩
- 🔗 国家标准 — GB/T 38662 物联网标识体系 Ecode 标识应用指南:openstd.samr.gov.cn/bzgk/std/newGbInfo?hcno=0B9BC95869E2A84AC9E1C02D0AFF584A ↩
- 🔗 NIST — IoT Device Identity(Federal Profile 8259A:每个 IoT 设备唯一识别):pages.nist.gov/FederalProfile-8259A/nontechnical/identity ↩
- 🔗 Nordic Semiconductor — Matter 开发指南(Vendor/Product ID、discriminator、setup passcode、NOC 证书/私钥):nordicsemi.cn/blog/matter-development ↩
- 🔗 CSA-IOT — Matter 1.4.2(DAC 设备认证证书 / CRL / Access Restriction Lists):csa-iot.org/newsroom/matter-1-4-2… ↩
- 🔗 Wikipedia / caralpha — VIN 车辆识别代号(ISO 3779/3780/4030,17 位三段式):en.wikipedia.org/wiki/VIN_number ↩
- 🔗 中国政府网 — 国家网络身份认证公共服务管理办法(网号/网证概念与申领方式,2025-07-15 施行):gov.cn/zhengce/202511/content_7049761.htm ↩
- 🔗 国家数字标准馆 — GA/T 1724-2020 居民身份网络认证 CTID 网络可信凭证和网络标识格式:ndls.org.cn/standard/detail/3f98cc6f… ↩
- 🔗 全国组织机构统一社会信用代码数据服务中心 — 统一社会信用代码构成(18 位,GB 32100-2015):cods.org.cn/cods/dmzs/index.html ↩
- 🔗 国家卫健委 — 医疗卫生机构患者主索引标准统一技术指南(2023 版)(MPI / EMPI / 电子健康卡跨域主索引):guifanku.com/903228.html ↩
- 🔗 国家卫健委 — WS/T 840-2025《患者身份识别管理标准》(患者唯一识别信息、身份证号/病案号):nhc.gov.cn/fzs/…/WST 840-2025 患者身份识别管理标准.pdf ↩
- 🔗 国家医保局 — 医保码全国用户超 10 亿(医保码=医保电子凭证,全国统一唯一标识、跨渠道通用):nhsa.gov.cn/art/2023/11/24/art_14_11548.html ↩
- 🔗 国家医保局 — 医疗保障信息平台便民服务相关技术规范(医保码定义、终端医保唯一序列号):nhsa.gov.cn/module/download/…(便民服务相关技术规范) ↩
- 🔗 中国医院协会信息专委会 — 薛万国:医院需要 EMPI 吗(MPI vs EMPI、标识域、IHE PIX):chima.org.cn/Html/News/Articles/13488.html ↩
- 🔗 国家新闻出版署 — 《关于进一步严格管理切实防止未成年人沉迷网络游戏的通知》答记者问(防沉迷实名验证系统、全部接入):12371.cn/2021/08/30/ARTI1630320976517831.shtml ↩
- 🔗 国家新闻出版署 — 《网络游戏行业防沉迷自律公约》(实名认证、精准识别用户):nppa.gov.cn/xxfb/ywdt/202109/t20210926_665036.html ↩
- 以下为第十三节「推送 SDK 设备级 ID」更正新增来源
- 🔗 个推 — 卓信 ID 概述(信通院解决方案;SDK 采集设备弱特征 → 服务端图计算聚类生成 RootID → 下发 ZID,有效期约 1 个月;同一设备 1 个月内不同 App 的 ZID 相同;AID 含 aaid 应用级 / vaid 同开发商级):docs.getui.com/getui/zxid/overview ↩
- 🔗 卓信 ID 官网(跨域设备标识:跨 APP、小程序、H5 平台运营数据打通;卸载分析、安全反欺诈、兼容 OAID):zxid.mobileservice.cn ↩
- 🔗 个推 — 消息推送 SDK 合规指南("用于生成唯一的推送目标 ID(CID)和设备 ID(GID)";卓信 ID 由中互智安/中国互联网协会提供):docs.getui.com/compliance ↩
- 🔗 个推 — 用户隐私政策(生成唯一的推送目标 ID(CID)和设备 ID(GID)):docs.getui.com/privacy ↩
- 🔗 极光 — 隐私政策(用 Android ID/GAID/OAID/UAID/AAID/IDFA/Boot ID 生成"脱敏的终端用户设备唯一性标识",用于推送/统计/画像;IMEI/MAC/IMSI 为可选补充):jiguang.cn/license/privacy ↩
- 🔗 极光 — 推送 SDK 合规指引(外部存储权限"用于避免对同一用户生成多个推送目标 ID(极光 RID)";合并链路;用户洞察/应用活跃时长统计):docs.jiguang.cn/jpush/client/jghgzy_a_i_h ↩
- 🔗 极光社区 — RegistrationID 设备唯一性(DeviceID 存 Settings + External Storage;用 IMEI/MAC/AndroidID 综合判断是否老设备):community.jiguang.cn/article/36680 ↩
- 🔗 极光 — 设备管理 API(registration_id 标注为"极光生成的设备唯一标识"):docs.jiguang.cn/jpush/server/push/rest_api_v3_device ↩
- 🔗 友盟 — 术语解释(新增用户以 UMID 作为唯一设备识别;UMID 为友盟自研设备 ID 生成算法):devs.umeng.com/docs/119267/detail/119422 ↩
- 🔗 友盟 — 用户账号及用户属性(umid 为"友盟生成的设备唯一标识",可与用户账号映射):developer.umeng.com/docs/119267/detail/2543745 ↩
- 🔗 友盟博客 — 移动应用统计基本原理及 UMID 方案(可区分统计:利用一个身份标识长期追踪单个设备):cnblogs.com/Umeng/p/3885497.html ↩
- 🔗 阿里云 — 设备标识体系的构成与生命周期(UTDID 利用系统公共存储组件"保证系统中不同的应用之间可以共享";DeviceID 为 EMAS 对外唯一设备 ID;Token 为厂商通道标识):help.aliyun.com/zh/document_detail/616675.html ↩
- 🔗 华为 — 开放匿名设备标识服务 OAID("OAID 是设备级标识符,同一台设备上不同的 App 获取到的 OAID 值一样";跨应用关联访问权限开关):developer.huawei.com/consumer/cn/doc/harmonyos-guides/oaid-service ↩
- 🔗 神策 — 标识用户 / 全域用户关联 IDM 3.0(业务 ID 分设备 ID、特定生态 ID、业务 ID 三类;ID 打通需同一条数据同时上报两个 ID):manual.sensorsdata.cn/sa/docs/tech_knowledge_user_idm3/v0205 ↩
- 🔗 中国光大银行 — 第三方 SDK 个人信息收集清单(卓信 ID 采集字段与"提供设备标识与安全风控服务"用途):yghsh.cebbank.com/static/app/agreement/useryinsi/annex/index3.html ↩
- 🔗 火山引擎 — 增长分析(DataFinder)device_id / web_id / anonymous_id 文档("可以做到同一台设备上的不同 App 可以用相同的 device_id";ssid/统一 ID 服务):volcengine.com/docs/ABtesting/Supporteduseruniqueidentifiers ↩
- 🔗 巨量学 — 品牌广告投放第三方监测说明(BDID = "巨量引擎下的整合归一 ID,替换原来的设备 ID 宏字段(IMEI、IDFA、OPENUDID 等)……同一设备在不同客户维度下 BDID 不相同",64 位小写):school.oceanengine.com/product_help/content/668400000011/113823 ↩
- 🔗 京东云 — 设备指纹产品页("为每一个访问您业务的移动设备建立全球唯一且稳定的设备 ID";"依托京东 20 余款 APP 的最佳实践";"生成和恢复算法"):jdcloud.com/cn/products/device-fingerprint ↩
- 🔗 京东云 — 设备指纹产品功能文档(生成设备唯一标识 / 设备风险识别):docs.jdcloud.com/cn/device-fingerprint/features ↩
- 🔗 京东星盾 — 设备指纹("设备指纹通过前后端技术以及算法为用户设备生成唯一的设备 ID"):dun.jd.com/core.html ↩
- 🔗 京东 EMOP — 设备唯一标识方案(okuuid)(京东主站 UUID 方案 = IMEI-MAC / AndroidID 降级;okuuid-jdmall"与主站打通、UUID 保持一致"):opendoc.jd.com/base/emop/module/UUID/Android.html ↩
- 🔗 京东会议 — 第三方 SDK 及个人信息传输情况(
com.jingdong.wireless.jdsdk:okuuid列为"日志上报设备标识"内部 SDK;运营主体京东叁佰陆拾度):meeting.jd.com/jdmeeting/agreement/third_party_sdk_cn.html ↩ - 🔗 网易易盾 — 设备指纹(设备 DNA 指纹)产品页(设备标识 / 智能追回 / 风险检测 / 设备信用体系):m.dun.163.com/product/dna ↩
- 🔗 网易数帆 — "全面升级!网易易盾发布设备 DNA 指纹系统"(客户端版 vs 服务端版;应用升级重装 / 系统更新后指纹不变):sq.sf.163.com/blog/article/324784564367876096 ↩
- 🔗 网易易盾 — "从应用端到服务端,设备指纹生成算法大变革"(服务端 F1/F2 多算法回溯找回;官方披露找回比例达 8.9%):dun.163.com/news/p/3334e58060e64207ad46139bab6da6ba ↩
- 🔗 网易易盾 — 设备指纹 Android 接入文档(采集字段与权限表;IMEI 自 SDK 1.7.2.3、SN 自 1.8.0 后不再采集;仅网络权限):support.dun.163.com/documents/609099986339037184?docId=609101009640161280 ↩
- 🔗 网易云音乐 — 个人信息第三方共享清单("网易基础 SDK"以"设备标识信息(Device ID)"用于基本网络服务 / 安全风控 / 日志收集 / 注册登陆;易盾设备安全 SDK):y.music.163.com/g/yida/3a56f958d00b4e1f9f9295196e06fbd1 ↩
- 🔗 网易云音乐 — 数据处理方法专利 CN122765062A(用带唯一令牌身份标识的令牌做在线设备数统计,解决"客户端无法生成设备 ID、设备 ID 冲突、设备 ID 分裂"):sohu.com/a/1076816707_114984 ↩
- 🔗 美团 — 美团优选团长隐私政策(采集设备型号 / 硬件序列号 / MAC / 唯一设备识别码 IMEI/MEID/IMSI/AndroidID/IDFA/IDFV/OAID/ICCID 等,用于账号 / 交易 / 系统运行安全):rules-center.meituan.com/m/detail/guize/440 ↩
- 🔗 美团 — 美团基本功能隐私政策(集成第三方 SDK 及数据共享说明):rules-center.meituan.com/m/detail/guize/2 ↩
- 🔗 美团技术团队 — 复杂风控场景下如何打造规则引擎 Zeus(风控核心 ="识别谁、什么时间、通过什么方式、做了什么事"):tech.meituan.com/2020/05/14/Meituan-Security-Zeus.html ↩
- 🔗 美团外卖 App 设备指纹风控分析(第三方逆向 ⚠:libmtguard.so / MTGuard、xid 与 dfpid、"APP 第一次运行用 UUID 与时间加密生成"、mtgsig):cnblogs.com/2014asm/p/15391247.html ↩
- 🔗 美团 SSO 登录过程分析(第三方逆向 ⚠:美团系 App 同签名共享 AndroidID,deviceInfo 换 token → 服务器返回跨 App 共享 unionid):hackmd.io/@UVyrJp_8SZKH6x-sSHFp1A/rJozPUTz3 ↩
- 🔗 人人都是产品经理 — 用户画像 ID 体系建设:以阿里、网易、美团、58 为例(网易"连通图划分 + 社区发现";美团注册用户以手机号为唯一标识;⚠ 二手来源):woshipm.com/user-research/4272693.html ↩
- 🔗 穿山甲 — 内容 SDK 第三方信息共享清单(采集 OAID / AndroidID / GAID / IDFA / IDFV / AAID / OOID 等;北京火山引擎科技):csjplatform.com/terms/28454 ↩
- 🔗 我的南京 App — 第三方 SDK 隐私协议(转化 SDK / RangersAppLog、增长营销套件 SDK 采集字段清单,字节 / 火山引擎):m.mynj.cn:11100/mynjWeb/protocol/ThirdSDk7.html ↩
- 🔗 中国广告协会 — CAID API 接入文档(iOS 广告行业统一设备标识,替代 IDFA;设备信息 RSA 加密上报):china-caa.org/uploads/downloads/digital/api_v1.15.pdf ↩
- 🔗 阿里云开发者社区 — 逆向分析 TikTok 设备指纹与设备注册(⚠ 第三方逆向:device_register 返回 device_id,注册因子含 openudid / clientudid / mac / google_aid / sig_hash):developer.aliyun.com/article/1329341 ↩
- 🔗 CSDN — 抖音设备注册机制逆向(⚠ 第三方逆向:device_id 与 install_id 的生成与校验):blog.csdn.net/weixin_29322553/article/details/158679833 ↩
- 🔗 快手隐私保护平台 — 基本功能隐私政策(浏览/播放记录设备信息 OAID、AndroidID、IDFA;详细版含 IDFV、运营商 UAID、Openudid、应用软件安装列表):privacy.kuaishou.com/policy ↩
- 🔗 快手游戏 — 隐私合规 / 快手联运 SDK(oaid 标注为"生成设备标识"必要字段;采集 OAID / GAID / AndroidID / SN / ICCID / 位置 / 传感器 / 运行中进程):ks-game-docs.kuaishou.com/guide/activity/5.secret.html ↩
- 🔗 GitHub — kuaishou_public(⚠ 第三方逆向:快手 EGID 设备注册、约 119 字段 EgidNano、AndroidID 缺失时随机生成 ANDROID_xxxxxxxx 存 SharedPreferences、did cookie):github.com/zero199901/kuaishou_public ↩
- 🔗 阿里云 — 风险识别 设备风险识别 SDK Android 接入(getDeviceToken 流程;权限表 INTERNET 必选 / READ_PHONE_STATE·存储 推荐;NO_UNIQUE_DEVICE_DATA = OAID/GAID/AndroidID;Token 约 600B / 2.5K):help.aliyun.com/zh/fraud-detection/developer-reference/device-risk-detection-sdk-for-android ↩
- 🔗 阿里云 — 设备风险识别 SDK 合规使用说明(字段分级:NO_UNIQUE_DEVICE_DATA / NO_IDENTIFY_DEVICE_DATA / NO_BASIC_DEVICE_DATA / NO_EXTRA_DEVICE_DATA,按 DataType 开关采集):help.aliyun.com/zh/fraud-detection/developer-reference/device-fraud-detection-sdk-compliance-description ↩
- 🔗 阿里云 — 设备风控服务(多端 SDK:App / Web / H5 / 小程序;deviceToken + 服务端返回风险标签与评分):help.aliyun.com/zh/fraud-detection/developer-reference/device-fingerprint-fraud-detection ↩
- 🔗 阿里云 — 第三方 SDK 收集使用信息说明(阿里安全 / 橙盾、淘宝、支付宝采集字段清单):terms.aliyun.com/legal-agreement/terms/suit_bu1_ali_cloud/suit_bu1_ali_cloud202012160957_66948.html ↩
- 🔗 GitHub — 拼多多 Android 加密算法分析(⚠ 第三方逆向:libpdd_secure.so、SecureNative / DeviceNative、info4 = AES-128-CBC 的自定义 TLV,约 33 个设备字段):github.com/mankezhou/Pdd-anti-token ↩
- 🔗 道满Python — 拼多多 anti_content 逆向(⚠ 第三方逆向:时间戳 + 浏览器/设备指纹 + 操作轨迹 + 动态盐,检测真实浏览器环境):daomanpy.com/spider/js-reverse-cases/pdd-anticontent-reverse ↩
- 🔗 拼多多开放平台 — 前端解密接入风控验证码(风控体系 + 前端检测 SDK pc.js):open.pinduoduo.com/application/document/browse?idStr=4531F8DD1AA73681 ↩
- 🔗 IETF — RFC 8981《Temporary Address Extensions for Stateless Address Autoconfiguration in IPv6》(临时地址随机化 IID,正式取代 RFC 4941):rfc-editor.org/rfc/rfc8981.html ↩
- 🔗 IETF — RFC 7721《Security and Privacy Considerations for IPv6 Address Generation Mechanisms》(固定 IID 导致基于地址的活动关联):datatracker.ietf.org/doc/html/rfc7721 ↩
- 🔗 IETF — RFC 7217《A Method for Generating Semantically Opaque Interface Identifiers with IPv6 SLAAC》:rfc-editor.org/info/rfc7217 ↩
- 🔗 IETF — RFC 8415《Dynamic Host Configuration Protocol for IPv6 (DHCPv6)》(DUID 定义,"跨重启稳定"):datatracker.ietf.org/doc/html/rfc8415 ↩
- 🔗 IETF — RFC 6355《Definition of the UUID-Based DHCPv6 Unique Identifier (DUID-UUID)》:datatracker.ietf.org/doc/html/rfc6355 ↩
- 🔗 FoxIO — JA4+ Network Fingerprinting(JA4 TLS 客户端指纹,取代 JA3;支持 QUIC;含 JA4H / JA4T 等):blog.foxio.io/ja4+-network-fingerprinting ↩
- 🔗 Cloudflare — JA3/JA4 fingerprint(Bot Management 文档;原文指出"移动 App 流量常在不同设备 / 用户上产生相同 JA3"):developers.cloudflare.com/bots/additional-configurations/ja3-ja4-fingerprint ↩
- 🔗 Akamai —《Passive Fingerprinting of HTTP/2 Clients》白皮书(SETTINGS|WINDOW_UPDATE|PRIORITY|伪头顺序):blackhat.com/docs/eu-17/materials/eu-17-Shuster-Passive-Fingerprinting-Of-HTTP2-Clients-wp.pdf ↩
- 🔗 p0f 被动 TCP/IP 栈指纹综述(初始 TTL 64/128/255、窗口、MSS、TCP 选项顺序 → OS 识别;JA4T):blog.crawlex.net/blog/p0f-passive-os-fingerprinting ↩
- 🔗 IETF —《Using Multicast DNS to protect privacy when exposing ICE candidates》(WebRTC 私网 IP 泄漏,mDNS 缓解):datatracker.ietf.org/doc/html/draft-ietf-rtcweb-mdns-ice-candidates-04 ↩
- 🔗 AmIUnique(INRIA,Laperdrix 等)— 浏览器指纹唯一性 / 稳定性数据(桌面 35.7% / 移动 18.5% 唯一;90 天 89% 仍唯一):amiunique.io;原始论文 dl.acm.org/doi/fullHtml/10.1145/3178876.3186097 ↩
- 🔗 DrawnApart(NDSS 2022,Laor 等)— 远程 GPU 指纹(执行单元时序差异区分同型号芯片,追踪时长 +67%):ndss-symposium.org/ndss-paper/drawnapart ↩
- 🔗 SensorID / Factory Calibration Fingerprinting of Sensors(IEEE S&P 2019 / TIFS 2020,Zhang 等,剑桥)— 传感器出厂校准指纹(iOS 约 67 bit、Pixel 4 约 57 bit;恢复出厂不变;iOS 12.2 / Android 11 缓解):cl.cam.ac.uk/~jz448/publication/TIFS.pdf ↩
- 🔗 Clock Skew Based Client Device Identification(IEEE;100 台设备偏移 67 ~ −499 ppm 可区分):ieeexplore.ieee.org/document/6184915 ↩
- 🔗 SAC 2025 —《On the Difficulty of NOT being Unique: Fingerprinting Users from Wi-Fi Data》(单次 BSSID 快照唯一识别 ~99%):dcc.fc.up.pt/~joaovilela/publications/sac2025.pdf ↩
- 🔗 INRIA —《RSSI-Based Fingerprinting of Bluetooth Low Energy Devices》(RSSI 分布破解 BLE 地址随机化,≤30 设备准确率约 0.99):inria.hal.science/hal-04161424 ↩
- 🔗 ⚠ 第三方 — Android 设备指纹采集与模拟器识别清单(Build.* / getprop / /proc/cpuinfo;Java·native·syscall 三层采集):github.com/msantiagodev/ACE-ANTICHEAT(61_emulator_detection_inventory.md) ↩
- 🔗 ⚠ 厂商自述 — 顶象 UnifyID 设备指纹(宣称 Web 跨浏览器、刷机 / 改机后指纹不变):yun88.com/product/3722.html ↩
- 🔗 ⚠ 厂商自述 — 同盾「北斗」设备指纹(硬件 / 软件 / 网络三层采集生成全局唯一设备 ID):xiaodun.com/product/bddevicefingerp ↩
- 🔗 ⚠ 厂商自述 — 数美设备指纹(关联硬件 / 系统 / 网络 / 状态,专有加密算法生成全局唯一设备标识):ishumei.com/product/bs-post-sdk.html ↩
- 🔗 ⚠ 逆向分析 — 某盾设备指纹算法分析(看雪,OLLVM+VMP 下还原出魔改 AES-128 CBC):bbs.kanxue.com/thread-288695.htm ↩
- 🔗 ⚠ 逆向分析 — 某 APP 设备风控分析及绕过(看雪,含 Magisk 检测与绕过失败复盘):bbs.kanxue.com/thread-288034.htm ↩
- 🔗 ⚠ 逆向分析 — 自动化采集 Android 系统级设备指纹对抗(看雪,五类指纹产生位置与对抗手段):bbs.kanxue.com/thread-281889.htm ↩
- 🔗 ⚠ 逆向分析 — 某 SDK 注册风控逆向(看雪,后台下发设备 id 为注册门槛):bbs.kanxue.com/thread-290710.htm ↩
- 🔗 技术分析 — 设备指纹的技术分析(阿里云开发者社区):developer.aliyun.com/article/977457 ↩
- 🔗 ⚠ 逆向分析 — 以攻击者角度学习某风控设备指纹产品(腾讯云,iOS 侧 constId 篡改成功):cloud.tencent.com/developer/article/1685044 ↩
- 🔗 ⚠ 逆向分析 — App 逆向百例 12:某电商 App Sign 分析(阿里云,Frida+Unidbg 还原京东 getSignFromJni):developer.aliyun.com/article/1330083 ↩
- 🔗 ⚠ 逆向分析 — 快手设备 did/egid 注册流程(爬虫逆向知识站,五步注册链路):lxspider.com/?p=1508 ↩
- 🔗 ⚠ 开源实现 — Android_CN_OAID:安卓设备唯一标识解决方案(可替代 MSA 统一 SDK,≈2874★):github.com/gzu-liyujiang/Android_CN_OAID ↩
- 🔗 ⚠ 开源实现 — Get_Oaid_CNAdid:各厂商 OAID 原生获取方法整合(北京数字联盟):github.com/shuzilm-open-source/Get_Oaid_CNAdid ↩
- 🔗 ⚠ 开源实现 — TikTok X-Gorgon/X-Argus/X-Ladon/X-Khronos 签名与设备注册(unidbg):github.com/ssovit/tiktok-x-argus-ladon-gorgon-khronos-unidbg ↩
- 🔗 ⚠ 开源实现 — TikTokDeviceGenerator:批量 device_register 设备生成:github.com/code-root/TikTokDeviceGenerator ↩
- 🔗 ⚠ 开源实现 — Kuaishou_Get_Did:生成快手 did(selenium 取 Cookie):github.com/1136623363/Kuaishou_Get_Did ↩
- 🔗 ⚠ 开源实现 — 快手 did 设备注册与 sig 签名(MD5 排序拼接):github.com/shenydowa/-did-sig-sign- ↩
- 🔗 ⚠ 开源实现 — 快手协议、签名算法实现(CPU.getClock() 签名):github.com/yantoumu/20201210-100308-742 ↩
- 🔗 ⚠ 开源实现 — iOS-UDID-Safari:经 Safari/mobileconfig 取 iOS 真实 UDID(机制已被 Apple 废弃,历史参考):github.com/shaojiankui/iOS-UDID-Safari ↩
- 🔗 ⚠ 逆向分析 — 使用 deepseek 分析某聊天 App 的 QIMEI 生成与 ollvm 理解(看雪,补第十二节空白):bbs.kanxue.com/thread-292900.htm ↩
- 🔗 ⚠ 逆向分析 — 某宝购物 App 设备风控 SDK-mtop 简单分析(看雪,iOS 侧 eeid 与风险字段):bbs.kanxue.com/thread-284241.htm ↩
- 🔗 ⚠ 逆向分析 — 某短视频指纹和纯算 sig3 逆向分析(吾爱破解,HMAC-SHA256+白盒 AES+CRC32):52pojie.cn/thread-2080428-1-1.html ↩
- 🔗 ⚠ 逆向分析 — iOS DeviceCheck:苹果设备身份链与黑灰产对抗的攻防博弈(吾爱破解,补第六节机制空白):52pojie.cn/thread-2114213-1-1.html ↩
- 🔗 ⚠ 逆向分析 — 某风控 SDK 逆向分析(腾讯云,注解改名 a1/a2 + 双层采集 + 反 ollvm):cloud.tencent.com/developer/article/2216958 ↩
数据来源标记约定:🔗 = 公开资料(附链接);🧪 = 本会话自测(本条报告未包含自测数据);⚠ = 推断/未验证。
本报告为桌面调研(desktop research),不含实机实测;所有数值与行为描述均来自上述公开来源,落地前建议在目标机型/系统版本上做兼容性验证。