唯一标识符最佳做法

本文档提供了相关指导,帮助您根据自己的用例为应用选择合适的标识符。

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

使用 Android 标识符的最佳做法

为了保护用户的隐私,请使用符合您应用场景且限制性最强的标识符。具体而言,请遵循以下最佳实践:

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

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

  3. 只针对用户画像或广告用例使用广告 ID。使用广告 ID 时,请始终尊重用户针对广告跟踪所做的选择。如果您必须将广告标识符与个人身份信息相关联,则只能在获得用户明确许可的情况下这样做。

  4. 请勿在广告 ID 重置后进行桥接。

  5. 对于所有其他用例(支付欺诈防范和电话服务除外),请尽可能使用 Firebase 安装 ID (FID) 或私密存储的 GUID。对于绝大多数非广告用例,FID 或 GUID 应该就足够了。

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

本指南的其余部分将详细介绍在开发 Android 应用时如何应用这些规则。

使用广告 ID

广告 ID 是可由用户重置的标识符,适用于广告用例。不过,在使用此 ID 时,请注意以下几点:

始终尊重用户重置广告 ID 的意图。 在未经用户同意的情况下,不得使用其他标识符或指纹将后续广告 ID 关联在一起,从而绕过用户重置。Google Play 开发者内容政策规定如下:

“…广告标识符重置后,在未获得用户明确许可的情况下,不得将新的广告标识符与先前的广告标识符或由先前的广告标识符所衍生的数据相关联。”

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

“…您必须遵从用户的‘选择停用针对用户兴趣投放广告’或‘选择停用广告个性化功能’设置。如果用户已启用此设置,您不得出于广告目的使用该广告标识符创建用户个人资料,也不得使用该广告标识符向用户投放个性化广告。允许的活动包括:内容相关广告投放、频次上限、转化跟踪、生成报表,以及安全性和欺诈检测。”

请注意,您使用的 SDK 可能会有与广告 ID 使用相关的隐私权或安全政策。 例如,如果您将 true 传递到 Google Analytics SDK 中的 enableAdvertisingIdCollection() 方法,请务必查看并遵守所有适用的 Analytics SDK 政策。

此外,请注意,Google Play 开发者内容政策要求广告 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 和广告 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 与广告 ID 之间建立明确关联。在上面的第一个示例中,这意味着 TABLE-01 中不包含 account_id 列。

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

    1. 使广告客户 ID 键控数据和 PII 的访问控制列表 (ACL) 保持不相交,以尽量减少同时存在于两个 ACL 中的个人或角色数量。
    2. 实施访问日志记录和审核,以检测和管理此规则的任何例外情况。

如需详细了解如何以负责任的方式使用广告 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)
  • 大区
  • 凭据,基于 Passpoint 配置文件中使用的凭据:
    • 用户凭证:用户名
    • 证书凭证:证书和证书类型
    • SIM 卡凭据:EAP 类型和 IMSI

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

下面列出了此变更会以哪些方式影响应用:

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

请注意,大多数开发者应使用 ConnectivityManager 的更高级别 API,而不是 NetworkInterface、getifaddrs() 或 Netlink 套接字等较低级别的 API。例如,需要获取当前路由最新信息的应用可以通过以下方式获取此信息:使用 ConnectivityManager.registerNetworkCallback() 监听网络更改,并调用网络关联的 LinkProperties.getRoutes()。

标识符特性

Android OS 提供了许多具有不同行为特征的 ID。 您应使用哪种 ID 取决于以下特征与您的应用场景的契合程度。不过,这些特征也会对隐私权产生影响,因此请务必了解这些特征如何相互影响。

范围

标识符作用域说明了哪些系统可以访问标识符。Android 标识符范围通常有三种:

  • 单一应用 - ID 仅限应用内部使用,其他应用无法访问。
  • 一组应用 - ID 可供一组预先定义的相关应用访问。
  • 设备 - ID 可供安装在设备上的所有应用访问。

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

重置性与持久性

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

  • 仅限会话期间 - 每次用户重新启动应用时都使用新的 ID。
  • 安装重置:每次用户卸载并重新安装应用时,都会使用新的 ID。
  • FDR 重置 - 每次用户恢复设备出厂设置时都使用新的 ID。
  • FDR 持久性 - ID 在恢复出厂设置后保持不变。

可重置性让用户能够创建与任何现有个人资料信息不关联的新 ID。标识符保留的时间越长、越可靠(例如在恢复出厂设置后仍保留),用户面临长期跟踪的风险就越大。如果标识符在应用重新安装时重置,则会降低持久性,并提供一种重置 ID 的方法,即使应用或系统设置中没有明确的用户控件可重置该 ID 也是如此。

唯一性

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

一般而言,您可以将用户账号标识符视为具有唯一性。也就是说,每个设备/账号组合都有一个唯一 ID。另一方面,标识符在群体中的唯一性越低,隐私保护效果就越好,因为标识符在跟踪单个用户方面的用处越小。

完整性保护和不可否认性

您可以使用难以伪造或重放的标识符来证明关联的设备或账号具有某些属性。例如,您可以证明设备不是垃圾内容发布者使用的虚拟设备。难以仿冒的标识符还能提供不可否认性。如果设备使用密钥对消息进行签名,则很难声称该消息是由其他人的设备发送的。不可否认性可能是用户想要的属性(例如在对付款进行身份验证时),也可能是用户不想要的属性(例如在发送了令其后悔的消息时)。

常见用例和适用的标识符

此部分为使用 IMEI 等硬件 ID 提供了替代方案。不建议使用硬件 ID,因为用户无法重置这些 ID,并且这些 ID 的范围限定为设备。在许多情况下,作用范围仅限于应用的标识符足以满足您的需求。

账号

运营商状态

在这种情况下,您的应用会使用运营商账号与设备的电话和短信功能进行交互。

建议使用的标识符:IMEI、IMSI 和 Line1

为什么这样建议?

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

移动服务订阅状态

在这种情况下,您需要将应用功能与设备上的特定移动服务订阅相关联。例如,您可能需要根据设备通过 SIM 卡进行的移动订阅来验证对某些付费应用功能的访问权限。

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

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

为什么这样建议?

某些应用目前可能正在使用 ICC ID 来实现此目的。由于 ICC ID 具有全局唯一性且不可重置,因此自 Android 10 起,只有具有 READ_PRIVILEGED_PHONE_STATE 权限的应用才能访问 ICC ID。从 Android 11 开始,Android 进一步限制了通过 getIccId() API 访问 ICCID 的权限,无论应用的目标 API 级别如何。受影响的应用应改为使用订阅 ID。

单点登录

在这种情况下,您的应用会提供单点登录体验,让用户能够将现有账号与贵组织相关联。

建议使用的标识符:与账号管理器兼容的账号,例如 Google 账号关联

为什么这样建议?

借助 Google 账号关联功能,用户可以将现有的 Google 账号与您的应用相关联,从而顺畅、更安全地访问贵组织的产品和服务。此外,您还可以定义自定义 OAuth 范围,以便仅共享必要的数据,并通过明确定义数据的使用方式来提高用户信任度。

广告

定位

在这种情况下,您的应用会构建用户兴趣画像,以便向用户展示更相关的广告。

建议使用的标识符:如果您的应用使用 ID 投放广告,并上传或发布到 Google Play,则该 ID 必须是广告 ID。

为什么这样建议?

这是一个与广告相关的用例,可能需要一个可在贵组织的不同应用中使用的 ID,因此使用广告 ID 是最合适的解决方案。根据 Google Play 开发者内容政策,对于广告用例,必须使用广告 ID,因为用户可以重置该 ID。

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

衡量

在这种情况下,您的应用会根据用户在同一设备上使用贵组织的应用时的行为创建用户个人资料。

建议使用的标识符:广告 ID 或 Play Install Referrer API

为什么这样建议?

这是一个与广告相关的用例,可能需要一个可在贵组织的不同应用中使用的 ID,因此使用广告 ID 是最合适的解决方案。如果您将某个 ID 用于广告用例,则该 ID 必须是广告 ID,因为用户可以重置该 ID。如需了解详情,请参阅 Google Play 开发者内容政策。

转化次数

在这种情况下,您需要跟踪转化情况,以检测您的营销策略是否成功。

建议使用的标识符:广告 ID 或 Play install referrer API

为什么这样建议?

这是一个与广告相关的用例,可能需要一个可在贵组织的不同应用中使用的 ID,因此使用广告 ID 是最合适的解决方案。根据 Google Play 开发者内容政策,对于广告用例,必须使用广告 ID,因为用户可以重置该 ID。

再营销

在这种情况下,您的应用会根据用户之前的兴趣展示广告。

建议使用的标识符:广告 ID

为什么这样建议?

这是一个与广告相关的用例,可能需要一个可在贵组织的不同应用中使用的 ID,因此使用广告 ID 是最合适的解决方案。根据 Google Play 开发者内容政策,对于广告用例,必须使用广告 ID,因为用户可以重置该 ID。

应用分析

在这种情况下,您的应用会评估用户的行为,以帮助您确定以下事项:

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

可能的解决方案包括:

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

应用开发

崩溃报告

在这种情况下,您的应用会收集有关其在用户设备上崩溃的时间和原因的数据。

建议使用的标识符:FID 或应用组 ID

为什么这样建议?

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

效果报告

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

建议使用的标识符: Firebase Performance Monitoring

为什么这样建议?

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

应用测试

在这种情况下,您的应用会出于测试或调试目的评估用户对您应用的体验。

建议使用的标识符:FID 或应用组 ID

为什么这样建议?

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

跨设备安装

在这种情况下,如果同一用户在多台设备上安装了您的应用,您的应用需要识别正确的应用实例。

建议使用的标识符:FID 或 GUID

为什么这样建议?

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

安全

滥用行为检测

在这种情况下,您需要尝试检测攻击后端服务的多个虚假设备。

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

为什么这样建议?

如需验证请求是否来自正版 Android 设备(而不是模拟器或其他伪装成其他设备的代码),请使用 Google Play Integrity API。

广告欺诈

在这种情况下,您的应用会检查用户在应用中的展示和操作是否真实且可验证。

建议使用的标识符:广告 ID

为什么这样建议?

根据 Google Play 开发者内容政策,广告用例必须使用广告 ID,因为用户可以重置该 ID。

数字版权管理 (DRM)

在这种情况下,您的应用希望防止欺诈性访问知识产权或付费内容。

建议使用的标识符:使用 FID 或 GUID 会强制用户重新安装应用,以规避内容限制,这足以阻止大多数人。如果这种保护措施还不够,Android 还提供了 DRM API,可用于限制对内容的访问,其中包含每个 APK 的标识符 Widevine ID。

用户偏好设置

在这种情况下,您的应用会在应用中保存每个设备的用户状态,尤其是对于未登录的用户。您可能会将此状态转移到同一设备上使用同一密钥签名的其他应用。

建议使用的标识符:FID 或 GUID

为什么这样建议?

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