代码透明度是一种针对使用 Android App Bundle 发布的应用的可选代码签名和验证机制。它使用仅由应用开发者持有的代码透明度签名密钥。
代码透明度独立于用于应用包和 APK 的签名方案。代码透明度密钥与使用 Play 应用签名时存储在 Google 安全基础架构上的应用签名密钥是分开且不同的。
代码透明度的工作原理
该过程通过在应用包构建完成后但在上传到 Play 管理中心进行分发之前,在应用包中包含一个代码透明度文件来工作。
代码透明度文件是一个 JSON Web Token (JWT),其中包含应用包中包含的 DEX 文件和原生库列表及其哈希值。然后使用仅由开发者持有的代码透明度密钥对其进行签名。
此代码透明度文件会传播到从应用包构建的基本 APK(具体来说是基本模块的主拆分)。然后可以验证
- APK 中存在的所有 DEX 和原生代码文件在代码透明度文件中都有匹配的哈希值。
- 应用中代码透明度签名密钥的公钥部分与开发者的公钥匹配(开发者必须通过单独的安全通道提供此公钥)。
这些信息共同验证了 APK 中包含的代码与开发者最初意图的代码相匹配,并且未被修改。
代码透明度文件不验证资源、素材资源、Android 清单或 lib/
文件夹中不包含 DEX 文件或原生库的任何其他文件。
代码透明度验证仅用于开发者和最终用户检查的目的,他们希望确保他们运行的代码与应用开发者最初构建和签名的代码相匹配。
已知限制
在某些情况下无法使用代码透明度
- 在清单中指定
sharedUserId
属性的应用。此类应用可能会与其他应用共享其进程,这使得很难确保它们正在执行的代码。 - 使用防篡改保护或任何其他在生成代码透明度文件后进行代码更改的服务将导致代码透明度验证失败。
- 在 API 级别低于 21 (Android 5.0) 的设备上使用旧版 Multidex 并使用功能模块的应用。当 Google Play 在 Android 5.0+ 设备上安装应用时,代码透明度将继续工作。代码透明度将在旧版操作系统上被禁用。
如何添加代码透明度
在向您的应用添加代码透明度之前,请确保您拥有可用于代码透明度签名的私钥和公钥对。这应该是一个唯一的密钥,不同于您用于 Play 应用签名的应用签名密钥,并且必须安全地保存,绝不能在您的组织之外共享。
如果您没有密钥,可以按照 签署您的应用 指南中的说明在您的机器上生成一个。代码透明度使用标准密钥库文件,因此即使该指南是针对应用签名的,密钥生成过程也是相同的。
使用 Android Gradle 插件
代码透明度支持需要 Android Gradle 插件版本 7.1.0-alpha03 或更高版本。要配置用于代码透明度签名的密钥,请在 bundle
块中添加以下内容。
Groovy
// In your app module's build.gradle file: android { ... bundle { codeTransparency { signing { keyAlias = "ALIAS" keyPassword = "PASSWORD" storeFile = file("path/to/keystore") storePassword = "PASSWORD" } } ... } }
Kotlin
// In your app module's build.gradle.kts file: android { ... bundle { codeTransparency { signing { keyAlias = "ALIAS" keyPassword = "PASSWORD" storeFile = file("path/to/keystore") storePassword = "PASSWORD" } } ... } }
所使用的密钥必须是您仅用于代码透明度的密钥,而不是 Play 应用签名所使用的应用签名密钥。
在命令行上使用 bundletool
代码透明度支持需要 bundletool 版本 1.7.0 或更高版本,您可以从 GitHub 下载。
运行以下命令将代码透明度添加到 Android App Bundle。所使用的密钥必须是您仅用于代码透明度的密钥,而不是 Play 应用签名所使用的应用签名密钥。
bundletool add-transparency \
--bundle=/MyApp/my_app.aab \
--output=/MyApp/my_app_with_transparency.aab \
--ks=/MyApp/keystore.jks \
--ks-pass=file:/MyApp/keystore.pwd \
--ks-key-alias=MyKeyAlias \
--key-pass=file:/MyApp/key.pwd
或者,如果您想使用自己的签名工具,可以使用 bundletool 生成未签名的代码透明度文件,在单独的环境中对其进行签名并将签名注入到应用包中
# Generate code transparency file
bundletool add-transparency \
--mode=generate_code_transparency_file \
--bundle=/MyApp/my_app.aab \
--output=/MyApp/code_transparency_file.jwt \
--transparency-key-certificate=/MyApp/transparency.cert
# Add code transparency signature to the bundle
bundletool add-transparency \
--mode=inject_signature \
--bundle=/MyApp/my_app.aab \
--output=/MyApp/my_app_with_transparency.aab \
--transparency-key-certificate=/MyApp/transparency.cert \
--transparency-signature=/MyApp/signature
验证应用的代码透明度
根据 APK 是安装在 Android 设备上还是本地下载到您的计算机上,有不同的方法来根据代码透明度文件验证代码。
使用 Bundletool 检查应用包或 APK 集
您可以使用 bundletool 来验证应用包或 APK 集中的代码透明度。使用 check-transparency
命令打印公共证书指纹
# For checking a bundle:
bundletool check-transparency \
--mode=bundle \
--bundle=/MyApp/my_app_with_transparency.aab
No APK present. APK signature was not checked.
Code transparency signature is valid. SHA-256 fingerprint of the code transparency key certificate (must be compared with the developer's public key manually): 01 23 45 67 89 AB CD EF ..
Code transparency verified: code related file contents match the code transparency file.
# For checking a ZIP containing app's APK splits:
bundletool check-transparency \
--mode=apk \
--apk-zip=/MyApp/my_app_with_transparency.zip
APK signature is valid. SHA-256 fingerprint of the apk signing key certificate (must be compared with the developer's public key manually): 02 34 E5 98 CD A7 B2 12 ..
Code transparency signature is valid. SHA-256 fingerprint of the code transparency key certificate (must be compared with the developer's public key manually): 01 23 45 67 89 AB CD EF ..
Code transparency verified: code related file contents match the code transparency file.
您可以选择指定要验证应用包或 APK 集的公共证书,这样您就不必手动比较哈希值了
bundletool check-transparency \
--mode=bundle \
--bundle=/MyApp/my_app_with_transparency.aab \
--transparency-key-certificate=/MyApp/transparency.cert
No APK present. APK signature was not checked.
Code transparency signature verified for the provided code transparency key certificate.
Code transparency verified: code related file contents match the code transparency file.
bundletool check-transparency \
--mode=apk \
--apk-zip=/MyApp/my_app_with_transparency.zip \
--apk-signing-key-certificate=/MyApp/apk.cert \
--transparency-key-certificate=/MyApp/transparency.cert
APK signature verified for the provided apk signing key certificate.
Code transparency signature verified for the provided code transparency key certificate.
Code transparency verified: code related file contents match the code transparency file.
使用 Bundletool 检查设备上安装的应用
要检查已安装在 Android 设备上的应用,请确保设备通过 ADB 连接到您的计算机,然后发出以下命令
bundletool check-transparency \
--mode=connected_device \
--package-name="com.my.app"
APK signature is valid. SHA-256 fingerprint of the apk signing key certificate (must be compared with the developer's public key manually): 02 34 E5 98 CD A7 B2 12 ..
Code transparency signature is valid. SHA-256 fingerprint of the code transparency key certificate (must be compared with the developer's public key manually): 01 23 45 67 89 AB CD EF ..
Code transparency verified: code related file contents match the code transparency file.
连接的设备透明度检查还可以选择根据您指定的公钥验证签名
bundletool check-transparency \
--mode=connected-device \
--package-name="com.my.app" \
--apk-signing-key-certificate=/MyApp/apk.cert \
--transparency-key-certificate=/MyApp/transparency.cert
APK signature verified for the provided apk signing key certificate.
Code transparency signature verified for the provided code transparency key certificate.
Code transparency verified: code related file contents match the code transparency file.