APK 签名方案 v3.1

概览

Android 13 支持 APK 签名方案 v3.1,即现有 APK 签名方案 v3 的改进版本。v3.1 方案解决了 APK 签名方案 v3 在轮替方面的一些已知问题。具体而言,v3.1 签名方案支持 SDK 版本定位功能,这会允许轮替定位到平台的更高版本。

v3.1 签名方案使用在 Android 12 或更低版本中无法识别的分块 ID。因此,平台会应用以下 signer 行为:

  • 搭载 Android 13 或更高版本的设备使用 v3.1 分块中的轮替 signer。
  • 搭载旧版 Android 的设备会忽略轮替 signer,而使用 v3 分块中的原始 signer。

尚未轮替其签名密钥的应用无需执行任何其他操作。每当这些应用选择轮替时,系统都会默认应用 v3.1 签名方案。

v3.1 签名分块

v3.1 签名分块将与 v3 签名分块具有相同内容,但前者会使用新的分块 ID,这些签名将仅可在搭载 Android 13 及更高版本的设备上可识别。这样,应用就能安全地轮替其签名密钥,而无需担心多目标 APK 会出问题,因为原始 signer 可用于在 v3 签名分块中为 APK 签名,而轮替 signer 可用于在 v3.1 签名分块中签名。这也使得平台可以在验证 v3.1 签名时,针对 v3 签名分块重复使用所有现有验证码。

默认情况下,每当签名配置中提供轮替密钥和谱系时,apksig 库都将使用 v3.1 签名分块。如果应用的 minSdkVersion 低于 Android 13,并且正在使用轮替密钥,还必须指定原始签名密钥,以便将其用于为 v3 签名分块中的 APK 签名。这类似于当前行为:如果 APK 定位到低于 Android 9 的版本,则必须指定原始 signer。

为了支持从特定 SDK 版本开始定位密钥轮替,apksig 库将提供新的 API,从而能够设置轮替的最低 SDK 版本。如果将低于 Android 13 的 SDK 版本指定为轮替支持的最低版本,系统将使用原始 v3 分块。仅当存在最低 SDK 版本设置为 Android 13 及更高版本的轮替时,才能使用 v3.1 签名分块。v3 签名分块将包含一个用于轮替最低 SDK 版本剥离保护的新属性。

APK 包括谱系 rotation-min-sdk-version 的值 v3 签名分块 v3.1 签名分块
默认值或任意值(以下面的 x 表示) 使用原始 signer 签名,定位到 Android 9 及更高版本 不存在
默认值 使用原始 signer 签名,定位到 Android 9 到 Android 12L 的任意版本 使用轮替 signer 签名,定位到 Android 13 及更高版本
x < 33 (Android 13) 使用轮替 signer 签名,定位到 Android 9 及更高版本 不存在
x >= 33 (Android 13) 使用原始 signer 签名,定位到 Android 9 到 Android (x-1) 的任意版本 使用轮替 signer 签名,定位到 Android x+

轮替相关问题

此平台中已解决以下轮替相关问题:

Android 12 修复程序

  • 只有两个应用中任一应用的当前 signer 在签名谱系中,或者是另一个应用的当前 signer,平台才会向发起请求的应用授予签名权限;如果两个应用都遵循签名密钥最佳实践并轮替到不同的签名密钥,此机制可以防止向发起请求的应用授予签名权限。
  • 平台的 APK 回滚功能无法回滚刚刚轮替其签名密钥的 APK,除非签名谱系中的上一个密钥具有回滚功能,但此功能会破坏轮替的目的,因为它允许上一个签名密钥为新软件包更新签名,并且回滚已轮替的密钥。
  • 如果某个 APK 仅使用了轮替密钥进行签名,并且之后使用谱系中的原始密钥和轮替密钥对 APK 进行了更新,则谱系中的轮替密钥仅在搭载 Android 11 和更高版本的设备上显示。

Android 11 修复程序

  • 未正确更新 PackageManager#checkSignatures 以检查两个软件包的原始签名密钥。这会导致使用原始签名密钥的插桩 APK 中断使用轮替签名密钥的应用的插桩。
  • sharedUserId 下的软件包具有相同的签名谱系。每当安装或更新 sharedUiserId 中具有已更新签名谱系的应用时,该应用的谱系会替换 sharedUserId 的共享谱系。也就是说,如果应用先前的签名谱系为 A -> B,并且应用的 sharedUserId 中已将谱系更新为 B -> C,则 sharedUserId 谱系将替换为 B -> C。同样,除非更改签名谱系,否则无法更新谱系中上一个 signer 的功能。

v4 集成

v4 签名方案使用提供给 apksigner 的签名配置;如果提供了多个轮替签名配置,系统会使用最新的轮替签名配置。在推出 v3.1 之前,v3 仅包含这一最新轮替签名配置,以便 v4 能够按原样使用此配置;这样一来,v4 签名方案就能支持轮替,因为该版本在 SigningInfo 中使用轮替签名密钥。虽然 v4 SigningInfo 不包含完整的签名谱系,但能够从 v3 签名分块提取此信息,使平台能够访问任何签名查询的谱系。如果使用 v3.1 定位所提供的 rotation-min-sdk-version 的轮替,通用 v3 配置将包括原始签名配置和最新轮替签名配置。v4 签名方案的扩展已得到构建,以纳入 v3.1 分块中的每个签名配置的附加签名信息分块。

验证

如需测试 v3.1 的实现,请在 cts/hostsidetests/appsecurity/src/android/appsecurity/cts/ 中运行 PkgInstallSignatureVerificationTest.java CTS 测试。

如需详细了解测试,请参阅 v3 中的验证部分。