唯一标识符的最佳实践

本文档提供了根据您的用例为应用选择适当标识符的指南。

有关 Android 权限的总体了解,请参阅权限概览。有关使用 Android 权限的具体最佳实践,请参阅应用权限最佳实践

使用 Android 标识符的最佳实践

为保护用户隐私,请使用满足应用用例的最严格的标识符。尤其应遵循以下最佳实践:

  1. 尽可能选择用户可重置的标识符。即使不使用不可重置的硬件 ID,您的应用也能实现大多数用例。
  2. 避免使用硬件标识符。在大多数用例中,您可以避免使用硬件标识符(例如国际移动设备身份码 (IMEI)),而不会限制所需功能。

    Android 10(API 级别 29)对不可重置的标识符(包括 IMEI 和序列号)施加了限制。您的应用必须是设备或资料所有者应用、拥有特殊运营商权限,或者拥有 READ_PRIVILEGED_PHONE_STATE 特权权限,才能访问这些标识符。

  3. 仅将 Advertising ID 用于用户分析或广告用例。使用 Advertising ID 时,请务必遵守用户关于广告跟踪的选择。如果您必须将广告标识符与个人身份信息相关联,则必须先征得用户的明确同意

  4. 不要桥接 Advertising ID 重置。

  5. 对于所有其他用例,除支付欺诈防范和电话功能外,应尽可能使用 Firebase 安装 ID (FID) 或私有存储的 GUID。对于绝大多数非广告用例,FID 或 GUID 足以满足要求。

  6. 使用适合您用例的 API,以最大限度地降低隐私风险。使用 DRM API 进行高价值内容保护,并使用 Play Integrity API 进行滥用防护。Play Integrity API 是在不产生隐私风险的情况下确定设备是否为正版的最简单方法。

本指南的其余部分将进一步阐述这些规则在 Android 应用开发中的应用。

使用 Advertising ID

Advertising ID 是用户可重置的标识符,适用于广告用例。但是,在使用此 ID 时,您需要记住一些关键点:

始终尊重用户重置广告 ID 的意愿。未经用户同意,请勿使用其他标识符或指纹将后续的 Advertising ID 连接起来,从而桥接用户重置操作。Google Play 开发者内容政策规定如下:

“...如果重置,新的广告标识符不得在未经用户明确同意的情况下与先前的广告标识符或从先前的广告标识符派生的数据相关联。”

始终尊重关联的个性化广告标记。Advertising ID 是可配置的,用户可以限制与 ID 关联的跟踪量。请务必使用 AdvertisingIdClient.Info.isLimitAdTrackingEnabled() 方法,确保您未规避用户的意愿。Google Play 开发者内容政策规定如下:

“...您必须遵守用户的“停用基于兴趣的广告”或“停用广告个性化”设置。如果用户启用了此设置,您不得将广告标识符用于出于广告目的创建用户资料或针对用户投放个性化广告。允许的活动包括情境广告、频次上限、转化跟踪、报告以及安全和欺诈检测。”

请注意您使用的与 Advertising ID 使用相关的 SDK 可能附带的隐私或安全政策。例如,如果您将 true 传递给 Google Analytics SDK 的 enableAdvertisingIdCollection() 方法,请务必查阅并遵守所有适用的 Analytics SDK 政策

此外,请注意,Google Play 开发者内容政策要求 Advertising ID“不得与个人身份信息关联,也不得与任何永久设备标识符(例如:SSAID、MAC 地址、IMEI 等)关联。”

举例来说,假设您想收集信息以填充具有以下列的数据库表:

TABLE-01
timestamp ad_id account_id clickid
TABLE-02
account_id name dob country

在此示例中,ad_id 列可以通过两个表中的 account_id 列与 PII 关联,如果您没有获得用户的明确许可,这将违反Google Play 开发者内容政策

请记住,广告主 ID 和 PII 之间的链接并非总是如此明确。可能存在同时出现在 PII 表和以广告 ID 为键的表中的“准标识符”,这也会导致问题。例如,假设我们将 TABLE-01 和 TABLE-02 更改如下:

TABLE-01
timestamp ad_id clickid dev_model
TABLE-02
timestamp demo account_id dev_model name

在这种情况下,如果点击事件足够少,仍然可以通过事件的时间戳和设备型号将广告主 ID TABLE-01 与 TABLE-02 中包含的 PII 进行关联。

虽然通常很难保证数据集中不存在此类准标识符,但您可以通过在可能的情况下泛化唯一数据来防止最明显的关联风险。在前面的示例中,这意味着降低时间戳的精度,以便每个时间戳都有多个具有相同型号的设备出现。

其他解决方案包括:

  • 不要设计明确将 PII 与 Advertising ID 关联的表。在上面的第一个示例中,这意味着不将 account_id 列包含在 TABLE-01 中。

  • 隔离和监控有权同时访问以 Advertising ID 为键的数据和 PII 的用户或角色的访问控制列表。通过严格控制和审计同时访问这两个源(例如,通过在表之间执行 JOIN 操作)的能力,可以降低 Advertising ID 和 PII 之间关联的风险。一般来说,控制访问意味着执行以下操作:

    1. 保持以广告主 ID 为键的数据和 PII 的访问控制列表 (ACL) 不相交,以最大限度地减少同时出现在这两个 ACL 中的个人或角色数量。
    2. 实施访问日志记录和审计,以检测和管理此规则的任何例外情况。

有关负责任地使用 Advertising ID 的更多信息,请参阅 AdvertisingIdClient API 参考文档。

使用 FID 和 GUID

识别设备上运行的应用实例的最简单方法是使用 Firebase 安装 ID (FID),这也是大多数非广告用例中推荐的解决方案。只有为其预置的那个应用实例才能访问此标识符,并且它是(相对)容易重置的,因为它仅在应用安装期间持久存在。

因此,与不可重置、设备范围的硬件 ID 相比,FID 提供了更好的隐私属性。有关更多信息,请参阅 firebase.installations API 参考文档。

在 FID 不切实际的情况下,您还可以使用自定义的全局唯一 ID (GUID) 来唯一标识应用实例。最简单的方法是使用以下代码生成您自己的 GUID:

Kotlin

var uniqueID = UUID.randomUUID().toString()

Java

String uniqueID = UUID.randomUUID().toString();

由于此标识符是全局唯一的,因此可用于标识特定的应用实例。为避免与跨应用链接标识符相关的问题,请将 GUID 存储在内部存储空间中,而不是外部(共享)存储空间中。有关更多信息,请参阅数据和文件存储概览页面。

不要使用 MAC 地址

MAC 地址是全局唯一的、用户无法重置,并且在恢复出厂设置后仍然存在。出于这些原因,为了保护用户隐私,在 Android 6 及更高版本上,对 MAC 地址的访问仅限于系统应用。第三方应用无法访问它们。

Android 11 中 MAC 地址可用性的变化

对于以 Android 11 及更高版本为目标的应用,Passpoint 网络的 MAC 地址随机化是按 Passpoint 配置文件进行的,根据以下字段生成唯一的 MAC 地址:

  • 完全限定域名 (FQDN)
  • Realm
  • 凭据,基于 Passpoint 配置文件中使用的凭据
    • 用户凭据:用户名
    • 证书凭据:证书和证书类型
    • SIM 凭据:EAP 类型和 IMSI

此外,非特权应用无法访问设备的 MAC 地址;只有具有 IP 地址的网络接口才可见。这会影响 getifaddrs()NetworkInterface.getHardwareAddress() 方法,以及发送 RTM_GETLINK Netlink 消息。

此更改对应用的影响列举如下:

  • NetworkInterface.getHardwareAddress() 对每个接口都返回 null。
  • 应用无法在 NETLINK_ROUTE 套接字上使用 bind() 函数。
  • ip 命令不返回有关接口的信息。
  • 应用无法发送 RTM_GETLINK 消息。

请注意,大多数开发者应使用 ConnectivityManager 的更高级别 API,而不是像 NetworkInterfacegetifaddrs() 或 Netlink 套接字这样的低级别 API。例如,需要最新当前路由信息的应用可以通过使用 ConnectivityManager.registerNetworkCallback() 监听网络变化并调用网络关联的 LinkProperties.getRoutes() 来获取此信息。

标识符特征

Android 操作系统提供了多种具有不同行为特征的 ID。应使用哪个 ID 取决于以下特征如何与您的用例协同工作。然而,这些特征也伴随着隐私隐患,因此了解这些特征如何相互作用至关重要。

范围

标识符范围解释了哪些系统可以访问该标识符。Android 标识符范围通常分为三类:

  • 单个应用:ID 对应用内部可见,其他应用无法访问。
  • 应用组:ID 对预定义的相关应用组可见。
  • 设备:ID 对设备上安装的所有应用可见。

标识符被授予的范围越广,其被用于跟踪目的的风险就越大。反之,如果标识符只能由单个应用实例访问,则无法用于跨不同应用中的事务来跟踪设备。

可重置性和持久性

可重置性和持久性定义了标识符的生命周期,并解释了如何重置它。常见的重置触发器包括:应用内重置、通过系统设置重置、启动时重置以及安装时重置。Android 标识符可以有不同的生命周期,但生命周期通常与 ID 的重置方式有关:

  • 仅会话:每次用户重启应用时都使用新的 ID。
  • 安装重置:用户每次卸载并重新安装应用时都使用新的 ID。
  • FDR 重置:用户每次恢复出厂设置时都使用新的 ID。
  • FDR 持久:ID 在恢复出厂设置后仍然存在。

可重置性使用户能够创建一个与任何现有个人资料信息分离的新 ID。标识符持久存在的时间越长、越可靠(例如在恢复出厂设置后仍然存在的标识符),用户遭受长期跟踪的风险就越大。如果在应用重新安装时重置标识符,则会降低其持久性,并提供一种重置 ID 的方法,即使在应用内或系统设置中没有明确的用户控制选项来重置它。

唯一性

唯一性确定了冲突的可能性;也就是说,在相关范围内存在相同的标识符。在最高级别,全局唯一标识符永远不会发生冲突,即使在其他设备或应用上也是如此。否则,唯一性级别取决于标识符的熵以及用于创建标识符的随机源。例如,使用安装日历日期(例如 2019-03-01)作为种子的随机标识符发生冲突的几率远高于使用安装 Unix 时间戳(例如 1551414181)作为种子的标识符。

一般来说,用户帐号标识符可以被认为是唯一的。也就是说,每个设备/帐号组合都有一个唯一的 ID。另一方面,标识符在人群中的唯一性越低,隐私保护就越大,因为它对跟踪单个用户的用处越小。

完整性保护和不可否认性

您可以使用难以欺骗或重放的标识符来证明关联的设备或帐号具有某些属性。例如,您可以证明该设备不是垃圾邮件发送者使用的虚拟设备。难以欺骗的标识符还提供不可否认性。如果设备使用密钥对消息进行签名,就很难声称是其他人的设备发送了该消息。不可否认性可能是用户希望拥有的属性,例如在验证支付时,也可能是用户不希望拥有的属性,例如在发送了后悔的消息时。

常见用例和适用的标识符

本节提供了使用硬件 ID(例如 IMEI)的替代方案。不鼓励使用硬件 ID,因为用户无法重置它们,并且它们的范围仅限于设备。在许多情况下,应用范围的标识符就足够了。

帐号

运营商状态

在此用例中,您的应用使用运营商帐号与设备的电话和短信功能进行交互。

推荐使用的标识符:IMEI、IMSI 和 Line1

为什么推荐这个标识符?

如果运营商相关功能需要使用硬件标识符,这是可以接受的。例如,您可以使用这些标识符在蜂窝运营商或 SIM 卡槽之间切换,或通过 IP 发送短信(对于 Line1)- 基于 SIM 卡的用户帐号。但是,对于非特权应用,我们建议使用帐号登录来在服务器端检索用户设备信息。原因之一是,在 Android 6.0(API 级别 23)及更高版本中,这些标识符只能通过运行时权限使用。用户可能会关闭此权限,因此您的应用应妥善处理这些例外情况。

移动订阅状态

在此用例中,您需要将应用功能与设备上的某些移动服务订阅相关联。例如,您可能需要根据设备通过 SIM 卡的移动订阅来验证对某些高级应用功能的访问权限。

推荐使用的标识符:Subscription ID API,用于识别设备上使用的 SIM 卡。

Subscription ID 提供了一个索引值(从 1 开始),用于唯一标识设备上使用的已安装 SIM 卡(包括物理和电子 SIM 卡)。通过此 ID,您的应用可以将其功能与给定 SIM 卡的各种订阅信息相关联。对于给定的 SIM 卡,除非设备恢复出厂设置,否则此值是稳定的。但是,在不同设备上,同一 SIM 卡可能具有不同的 Subscription ID,或者不同 SIM 卡在不同设备上具有相同的 ID。

为什么推荐这个标识符?

某些应用目前可能出于此目的使用 ICC ID。由于 ICC ID 是全局唯一的且不可重置,自 Android 10 起,访问权限已限制为拥有 READ_PRIVILEGED_PHONE_STATE 权限的应用。从 Android 11 开始,无论应用的目标 API 级别如何,Android 进一步通过 getIccId() API 限制了对 ICCID 的访问。受影响的应用应迁移至使用 Subscription ID。

单点登录

在此用例中,您的应用提供单点登录体验,允许用户将现有帐号与您的组织相关联。

推荐使用的标识符:帐号管理器兼容帐号,例如 Google 帐号关联

为什么推荐这个标识符?

Google 帐号关联允许用户将现有 Google 帐号与您的应用关联,从而为用户提供无缝、更安全地访问您组织产品和服务的体验。此外,您可以定义自定义 OAuth 范围,仅共享必要数据,并通过清晰定义如何使用其数据来提高用户信任度。

广告

定位

在此用例中,您的应用会建立用户的兴趣档案,以便向他们展示更相关的广告。

推荐使用的标识符:如果您的应用使用 ID 进行广告活动并上传或发布到 Google Play,则该 ID 必须是 Advertising ID。

为什么推荐这个标识符?

这是一个与广告相关的用例,可能需要一个在您组织不同应用之间都可用的 ID,因此使用 Advertising ID 是最合适的解决方案。根据Google Play 开发者内容政策,Advertising ID 的使用对于广告用例是强制性的,因为用户可以重置它。

无论您是否在应用中共享用户数据,如果您出于广告目的收集和使用用户数据,您都需要在 Play 管理中心的“应用内容”页面中的数据安全部分声明广告用途。

衡量

在此用例中,您的应用会根据用户在同一设备上跨您组织的应用的行为创建用户资料。

推荐使用的标识符:Advertising ID 或 Play 安装引荐来源 API

为什么推荐这个标识符?

这是一个与广告相关的用例,可能需要一个在您组织不同应用之间都可用的 ID,因此使用 Advertising ID 是最合适的解决方案。如果您将 ID 用于广告用例,则该 ID 必须是 Advertising ID,因为用户可以重置它。在Google Play 开发者内容政策中了解更多信息。

转化

在此用例中,您正在跟踪转化,以检测您的营销策略是否成功。

推荐使用的标识符:Advertising ID 或 Play 安装引荐来源 API

为什么推荐这个标识符?

这是一个与广告相关的用例,可能需要一个在您组织不同应用之间都可用的 ID,因此使用 Advertising ID 是最合适的解决方案。根据Google Play 开发者内容政策,Advertising ID 的使用对于广告用例是强制性的,因为用户可以重置它。

再营销

在此用例中,您的应用会根据用户之前的兴趣展示广告。

推荐使用的标识符:Advertising ID

为什么推荐这个标识符?

这是一个与广告相关的用例,可能需要一个在您组织不同应用之间都可用的 ID,因此使用 Advertising ID 是最合适的解决方案。根据Google Play 开发者内容政策,Advertising ID 的使用对于广告用例是强制性的,因为用户可以重置它。

应用分析

在此用例中,您的应用会评估用户的行为,以帮助您确定以下事项:

  • 您的组织的其他哪些产品或应用可能适合该用户。
  • 如何让用户对使用您的应用保持兴趣。
  • 衡量已退出登录或匿名用户的用量统计信息和分析数据。

可能的解决方案包括:

  • App Set ID:App Set ID 允许您分析用户在您组织拥有的多个应用中的行为,前提是您不将用户数据用于广告目的。如果您以搭载 Google Play 服务的设备为目标,我们建议您使用 App Set ID。
  • Firebase ID (FID):FID 的范围限定于创建它的应用,这使得该标识符无法用于跨应用跟踪用户。它也很容易重置,因为用户可以清除应用数据或重新安装应用。创建 FID 的过程很简单;请参阅 Firebase 安装指南。

应用开发

崩溃报告

在此用例中,您的应用会收集有关其何时、为何在用户的设备上崩溃的数据。

推荐使用的标识符:FID 或 App Set ID

为什么推荐这个标识符?

FID 的范围限定于创建它的应用,这使得该标识符无法用于跨应用跟踪用户。它也很容易重置,因为用户可以清除应用数据或重新安装应用。创建 FID 的过程很简单;请参阅 Firebase 安装指南。App Set ID 允许您分析用户在您组织拥有的多个应用中的行为,前提是您不将用户数据用于广告目的。

性能报告

在此用例中,您的应用会收集性能指标(例如加载时间和电池用量),以帮助提高应用质量。

推荐使用的标识符:Firebase Performance Monitoring

为什么推荐这个标识符?

Firebase Performance Monitoring 可帮助您关注最重要的指标,并测试您的应用最近更改的影响。

应用测试

在此用例中,您的应用会评估用户使用应用的体验,用于测试或调试目的。

推荐使用的标识符:FID 或 App Set ID

为什么推荐这个标识符?

FID 的范围限定于创建它的应用,这使得该标识符无法用于跨应用跟踪用户。它也很容易重置,因为用户可以清除应用数据或重新安装应用。创建 FID 的过程很简单;请参阅 Firebase 安装指南。App Set ID 允许您分析用户在您组织拥有的多个应用中的行为,前提是您不将用户数据用于广告目的。

跨设备安装

在此用例中,当同一用户在多个设备上安装您的应用时,您的应用需要识别正确的应用实例。

推荐使用的标识符:FID 或 GUID

为什么推荐这个标识符?

FID 专门为此目的而设计;其范围仅限于应用,因此无法用于跨不同应用跟踪用户,并且在重新安装应用时会重置。在极少数情况下,如果 FID 不足,您还可以使用 GUID。

安全性

滥用检测

在此用例中,您正在尝试检测多个虚假设备攻击您的后端服务。

推荐使用的标识符:Google Play Integrity API 完整性令牌

为什么推荐这个标识符?

要验证请求是否来自真实的 Android 设备(而不是模拟器或其他模拟设备的程序代码),请使用 Google Play Integrity API

广告欺诈

在此用例中,您的应用会检查用户在您的应用中的曝光和操作是否真实且可验证。

推荐使用的标识符:Advertising ID

为什么推荐这个标识符?

根据Google Play 开发者内容政策,Advertising ID 的使用对于广告用例是强制性的,因为用户可以重置它。

数字版权管理 (DRM)

在此用例中,您的应用希望保护知识产权或付费内容免受欺诈性访问。

推荐使用的标识符:使用 FID 或 GUID 会迫使用户重新安装应用以规避内容限制,这对于大多数人来说足以构成一种障碍。如果这还不足以提供保护,Android 提供了 DRM API,可用于限制对内容的访问,其中包含每个 APK 的标识符,即 Widevine ID。

用户偏好设置

在此用例中,您的应用会在您的应用上保存每个设备的用户状态,特别是对于未登录的用户。您可能需要将此状态转移到同一设备上使用相同密钥签名的另一个应用。

推荐使用的标识符:FID 或 GUID

为什么推荐这个标识符?

不建议通过重新安装来持久保存信息,因为用户可能希望通过重新安装应用来重置其偏好设置。