为什么APK文件需要签名?
每个 Android 应用程序在安装之前都必须经过数字签名。签名有几个目的:
- 验证应用程序开发者的身份
- 确保APK未被篡改
- 允许 Android 将应用程序更新与原始版本相匹配
- 需要在所有 Android 设备上安装
需要桌面工具
APK 签名需要命令行工具(JDK / Android SDK)。这无法在网络浏览器中完成。请按照以下指南在您的计算机上签署 APK。
方法一:使用apksigner签名(推荐)
apksigner 是 Google 官方 APK 签名工具,包含在 Android SDK Build Tools 中。
第 1 步:生成密钥库
keytool -genkey -v -keystore my-release-key.jks \
-keyalg RSA -keysize 2048 -validity 10000 \
-alias my-key-alias
第 2 步:签署 APK
apksigner sign --ks my-release-key.jks \
--ks-key-alias my-key-alias \
--out signed-app.apk unsigned-app.apk
第三步:验证签名
apksigner verify --verbose signed-app.apk
方法 2:使用 jarsigner 签名(旧版)
# Sign
jarsigner -verbose -sigalg SHA256withRSA \
-digestalg SHA-256 \
-keystore my-release-key.jks \
app-unsigned.apk my-key-alias
# Verify
jarsigner -verify -verbose app-signed.apk
第四步:Zipalign(重要!)
签名后,使用 zipalign 优化 APK:
zipalign -v 4 signed-app.apk aligned-app.apk
调试签名(用于测试)
出于测试目的,您可以使用默认的 Android 调试密钥库:
# Location of debug keystore:
# Linux/Mac: ~/.android/debug.keystore
# Windows: C:\Users\{USERNAME}\.android\debug.keystore
# Sign with debug key
apksigner sign --ks ~/.android/debug.keystore \
--ks-key-alias androiddebugkey \
--ks-pass pass:android \
app.apk
签名工具比较
| 指标 | apk签名者 | 贾西格纳 |
|---|---|---|
| V1签名 | ||
| V2签名 | ||
| V3签名 | ||
| 受到推崇的 | 遗产 |
APK 签名者 — 常见问题
有关 APK 签名、密钥库和 Android 代码签名的常见问题
为什么对齐顺序(zipalign 在 apksigner 之前)在 Android 11-15 上很重要
开发人员和修改者在签署修改或合并的 APK 时最常犯的错误之一是运行 zipalign 后 签署包,或者使用 Java 的旧版 jarsigner 实用程序而不是 Google 的 Android SDK apksigner。由于 APK 签名方案 v2 和 v3 在 ZIP 存档的整个二进制布局上计算加密哈希,因此在签名后使用 zipalign 修改字节偏移量会立即使 v2/v3 签名块失效。
从 Android 11(API 级别 30)开始,并在 Android 14 和 15 上严格执行,PackageManager 对于任何针对现代 SDK 级别的 APK 都需要两个不可协商的条件:
- 未压缩的 4 字节对齐 resources.arsc: 编译的资源表 (resources.arsc) 必须以未压缩的方式存储 (STORED) 并在 4 字节边界上对齐,以便 Android 可以直接对其进行内存映射 (mmap),而无需将其复制到 RAM 中。始终执行 zipalign -p -f -v 4 input.apk aligned.apk 前 签名。
- 强制 v2+ 签名块: 使用 jarsigner(仅写入 v1 META-INF/ 签名)对针对 API 30+ 的 APK 进行签名将导致 Android 11-15 拒绝使用 INSTALL_PARSE_FAILED_NO_CERTIFICATES 进行安装。使用上面的交互式命令生成器为您的密钥库构建准确的 apksigner --v2-signing-enabled=true 命令,或在我们的 APK签名验证器 中验证您的签名输出。