概览
Android 13 支持 APK 签名方案 v3.1,这是对现有 APK 签名方案 v3 的改进。v3.1 方案解决了 APK 签名方案 v3 在轮替方面的一些已知问题。特别是,v3.1 签名方案支持 SDK 版本定位,这允许轮替以定位平台的更高版本。
v3.1 签名方案使用 Android 12 或更低版本无法识别的块 ID。因此,平台应用以下签名者行为
- 运行 Android 13 或更高版本的设备使用 v3.1 块中的轮替签名者。
- 运行旧版 Android 的设备会忽略轮替签名者,而是使用 v3 块中的原始签名者。
尚未轮替其签名密钥的应用无需执行任何其他操作。每当这些应用选择轮替时,系统默认应用 v3.1 签名方案。
v3.1 签名块
v3.1 签名块的内容将与 v3 签名块相同,但由于使用了新的块 ID,这些签名仅在运行 Android 13 及更高版本的设备上才能被识别。这允许应用安全地轮替其签名密钥,而无需担心多目标 APK,因为原始签名者可用于在 v3 签名块中对 APK 进行签名,而轮替签名者可在 v3.1 签名块中对 APK 进行签名。这也允许平台在验证 v3.1 签名时重用 v3 签名块的所有现有验证代码。
默认情况下,当签名配置中提供轮替密钥和沿袭时,apksig
库将使用 v3.1 签名块。如果应用的 minSdkVersion
小于 Android 13 且正在使用轮替密钥,则还必须指定原始签名密钥,以便可用于在 v3 签名块中对 APK 进行签名。这类似于当前行为,如果 APK 定位的版本早于 Android 9,则需要原始签名者。
为了支持从特定 SDK 版本开始定位密钥轮替,apksig
库将公开新的 API,这些 API 将允许为轮替设置最低 SDK 版本。如果指定的轮替支持最低版本 SDK 版本小于 Android 13,则将使用原始 v3 块。仅当存在轮替且轮替的最低 SDK 版本设置为 Android 13 及更高版本时,才使用 v3.1 签名块。v3 签名块将具有用于轮替最低 SDK 版本剥离保护的新属性。
APK 包含沿袭 | rotation-min-sdk-version 的值 | v3 签名块 | v3.1 签名块 |
---|---|---|---|
否 | 默认值或任何值(以下用x表示) | 使用原始签名者签名,定位 Android 9 及更高版本 | 不存在 |
是 | 默认值 | 使用原始签名者签名,定位 Android 9 到 12L | 使用轮替签名者签名,定位 Android 13 及更高版本 |
是 | x < 33 (Android 13) | 使用轮替签名者签名,定位 Android 9 及更高版本 | 不存在 |
是 | x >= 33 (Android 13) | 使用原始签名者签名,定位 Android 9 - (x-1) | 使用轮替签名者签名,定位 x+ |
与轮替相关的问题
平台中已解决以下与轮替相关的问题
Android 12 修复
- 仅当请求应用的当前签名者在另一个应用的签名沿袭中,或者是另一个应用的当前签名者时,平台才会向请求应用授予签名权限;如果两个应用遵循签名密钥最佳实践并轮替到不同的签名密钥,则会阻止向请求应用授予签名权限。
- 平台的 APK 回滚功能无法回滚刚刚轮替了签名密钥的 APK,除非签名沿袭中的上一个密钥具有回滚功能,但此功能会破坏轮替的目的,因为它允许使用上一个签名密钥对新的软件包更新进行签名并回滚轮替的密钥。
- 仅使用轮替密钥签名的 APK 稍后使用原始密钥和沿袭中的轮替密钥签名的 APK 进行更新时,在运行 Android 11 及更早版本的设备上只会显示沿袭中的轮替密钥。
Android 11 修复
PackageManager#checkSignatures
未正确更新以检查两个软件包的原始签名密钥。这破坏了对使用轮替签名密钥且 instrumentation APK 使用原始签名密钥的应用的 instrumentation。- 在
sharedUserId
下的软件包共享其签名沿袭。每当在sharedUiserId
中安装或更新具有更新签名沿袭的应用时,该应用的沿袭将替换sharedUserId
的共享沿袭(也就是说,如果应用的签名沿袭为 A -> B,并且在sharedUserId
中使用沿袭 B -> C 更新了应用,则sharedUserId
沿袭将被 B -> C 替换)。同样,除非更改签名沿袭,否则无法更新沿袭中上一个签名者的功能。
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 中的验证部分。