漫谈唯一设备 ID

漫谈唯一设备 ID

一、前言

​ 近期在帮助公司测试不同品牌设备,同一设备不同纬度关于其唯一设备ID的变化。测试使用的项目是 GitHub 上的一个开源项目 。写了一个demo进行测试。为了更好的理解与测试,所以上网了解并学习了有关概念以及这方面行业动向。

​ 设备 ID,简单来说就是一串符号(或者数字),用来映射现实种的硬件设备。如果这些符号和设备是一一对应的,则可称之为“唯一设备 ID(Unique Device Identifier)”。

​ 然而不幸的是,对于 Android 平台而言,没有稳定的 API 可以让开发者获取到这样的设备 ID。开发者通常遇到这样的困境:随着项目的演进,越来越多的地方需要用到设备 ID;然而随着 Android 版本的升级,获取设备 ID 却越来越难了;加上 Android 平台碎片化的问题,获取设备 ID 之路,可以说是步履艰难。


二、设备 ID 的作用

关于设备 ID 的作用,大概可以分为下面几点:

  • 统计需求。统计需求是设备 ID 最常见的用途,包括DAU,MAU的统计,行为统计,广告激活统计。
  • 业务需求。设备 ID 通常也用于业务种,比如结合行为统计做用户画像,以为用户提供个性化的服务,大家感受比较明显的就是新闻类和电商类的 APP 了。这类操作,有利有弊,仁者见仁智者见智。又如,定向推送,不一定是广告推送,错误修复,内测推送等也会用到设备 ID。还是一些和特定业务结合的用途,比如构造分布式 ID 等。
  • 风控需求。设备 ID 还可用于防刷单,反作弊等。当然,风控需求仅靠设备 ID是无法完成的,通常需要简历一套反作弊系统。笔者在实习的工作岗位便是和这个有关。关于这方面的内容,难以一言以蔽之,这里不多做展开。

三、获取设备 ID 的 API

获取设备标识的 API D屈指可数,而且或多或少都有一些问题。

常规的 API 有以下这些:

IMEI

IMEI 本该是最理想的设备 ID,具备唯一性,恢复出厂设置不会变化(真正的设备相关)。然而,获取 IMEI 需要 READ_PHONE_STATE 权限,很麻烦。尤其是 Android 6.0 之后,这类权限需要动态申请,很多用户可能会选择拒绝授权。我每看到,有的 APP 不授权这个权限就无法使用,这可能会降低用户对 APP 的好感度。而且,Android 10.0 彻底禁止第三方应用获取设备的 IMEI,即使申请了 READ_PHONE_STATE 权限。所以,如果是新 APP,不建议用 IMEI 作为设备标识;如果已经使用 IMEI 作为标识,要赶紧做兼容工作了,尤其是做设备标识和 IMEI 的映射。

设备序列号

通过 android.os.Build.SERIAL 获得,由厂商提供。如果厂商比较规范的话,设备序列号 + android.os.Build.MANUFACTURER 应该能唯一标识设备。但现实是并非所有厂商都按规范来,尤其是早期的设备。最致命的是,Android 8.0 以上,android.osBuild.SERIAL 总返回”unknow“;若要获取序列号,可调用 Build.getSerial(),但是需要申请 READ_PHONE_STATE 权限。到了 Android 10.0 以上,则和 IMEI 一样,也被禁止获取了。总的来说,设备序列号有点鸡肋:食之无味,弃之可惜。

MAC 地址

获取 MAC 地址也是越来越困难了,Android 6.0 以后通过 WifiManager 获取到的 MAC 将是固定的:02:00:00:00:00:00,再后来连读取 /sys/class/net/wlan0/address 也获取不到了。

Android_ID

Android_ID 是获取门槛最低的,不需要任何权限,64bit 的取值范围,唯一性算是很好的了。但是不足之处也很明显:

  1. 刷机root恢复出厂设置等会使得 Android_ID 改变;
  2. Android 8.0 之后,Android_ID 的规则发生了变化:
    对于升级到 8.0 之前安装的应用,Android_ID 会保持不变。如果卸载后重新安装的话,Android_ID 将会改变。
    对于安装在 8.0 系统的应用来说,Android_ID 根据应用签名和用户的不同而不同。Android_ID的唯一决定于应用签名、用户和设备三者的组合。

两个规则导致的结果就是:

  • 第一,如果用户安装 APP 的设备是 8.0 以下,后来卸载了,升级到 8.0 之后又重装了应用, Android_ID 不一样;
  • 第二,不同签名的 APP,获取到的 Android_ID 不一样。

其中第二点可能对于广告联盟之类的有所影响。

还有就是,要排除非法 Android_ID,有些设备在某些版本的时候 Android_ID 是固定的,排除的方法除了上网检索之外,最好服务端能帮下忙。

例如,在插入服务器设备 ID 表的同时检测一下是否有重复的 Android_ID ,有的话重复量有多少,如果多的话给下报警。

Widevine ID

Widevine ID 是用于数字版权管理(DRM)的 Widevine 模块为每个设备分配的唯一标识符。Widevine ID 获取也是不需要权限的。但貌似有些鸡肋,可能为空,在一些设备上还可能造成卡死或者闪退。

Pseudo ID

通常是在无法获取稳定的设备标识时,通过系统某些属性组合生成的一个“伪唯一”设备 ID。不是真正的设备 ID,而是一组设备属性拼接 + hash 得出的一种替代方案。

GUID

GUID 是一种用于标识对象、设备、实体等的 128 位唯一的 ID,可用于分布式系统种生成不会重复的标记。它是 UUID 的一种实现标准,两者在大多数上下文中可以视为等价。

Canvas Fingerprint

目的是在不依赖 CookieLocalStorage设备 ID 等传统手段的前提下,唯一标识用户的设备或浏览器。该 ID 的生成依赖于 字体渲染图形抗锯齿画布合成方式驱动版本。但也正是因为这些因素导致即使是相同型号的设备,该值的输出也可能略不同,生成的 hash 也随之变化。

OAID

OAID 是中国 Android 生态中提出的一个用于替代设备唯一标识的方案,主要由 移动安全联盟 推出,目的是 在不侵犯用户隐私的前提下,实现设备标识和广告追踪功能,它的关键特性如下:

  • 匿名性。与设备和厂商绑定,但不关联真实用户身份;
  • 可重置。用户可在设置中手动重置 OAID (如广告标识)
  • 可关闭。用户选择关闭广告标识符,OAID 将不可用;
  • 无需权限。不需要任何权限即可获取,适用于 Android 6.0+;
  • 厂商实现。需要厂商系统预装支持 MSA SDK 或实现接口。

AAID

AAID 是 Google 提供的用于广告和用户行为分析的设备标识符,目的是在保护用户隐私的前提下,实现对设备的匿名识别和广告追踪。主要特点:

  • 唯一性。每个设备唯一,用户可重置;
  • 保护隐私安全。匿名且可由用户重置和限制;
  • 不需要敏感权限。

国产系统需要安卓 Google Play Services 才能获取 AAID.

EMMCID

EMMCID 是指设备中 eMMC 存储芯片的唯一标识符(CID,全称:Card Identification Number),常被称作 eMMC CID。它是 eMMC 存储设备的硬件级别序列号,在Android 和其他嵌入式系统中,有时被用作设备唯一标识的一部分(尤其是在一些系统厂商、ROM厂商、反作弊或风控场景中)。

  • 什么是 eMMC? 是一种内嵌式存储芯片,用于手机、平板等设备中,和 UFS 一样属于主存储芯片。

  • EMMCID 是啥?

  • 字段 长度 含义
    MID 8bit Manufacturer ID(厂商)
    OID 16bit OEM/Application ID
    PNM 40bit Product name(产品名)
    PRV 8bit Product revision
    PSN 32bit Product serial number
    MDT 12bit Manufacturing date
    CRC 7bit 校验位

VAID

是 Android 设备标识体系中的一个标识符,它属于 中国移动智能终端联盟 推出的一套设备唯一标准体系,和 OAID、AAID、UDID 并列,用于用户身份识别与广告归因场景中。是 MSA 标准中定义的面向厂商应用的广告标识符,**由设备系统提供,对同一设备 + 同一厂商下的应用是相同的,而对其他厂商应用不可见。**特点总结:

  • 设备唯一性。同一设备、同一厂商下的应用拿到的 VAID 是一样的;
  • 厂商隔离。不同厂商 App 拿到不同 VAID(即便同设备);
  • 隐私合规。用户可重置,也可关闭广告追踪权限;
  • 不可跨厂商跟踪。防止广告平台在不同厂商 App 之间追踪用户行为。

四、参考


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1621925986@qq.com

💰

×

Help us with donation