应用签名配置
Android 要求所有 APK 必须经过数字签名后才能安装。应用签名用于验证应用的作者身份,并确保应用未被篡改。
签名密钥类型
调试密钥
调试构建自动使用调试密钥库签名,位于:
~/.android/debug.keystore (macOS/Linux)
C:\Users\<username>\.android\debug.keystore (Windows)特点:
- 由 Android Studio 自动创建
- 不安全,仅用于开发和测试
- 有效期 365 天
- 密码和别名已知:
android/androiddebugkey
上传密钥
用于向 Google Play 上传应用的密钥。Google Play 使用 Play 应用签名功能,会用自己的发布密钥重新签名。
应用签名密钥
最终安装到用户设备的 APK 所使用的密钥。如果使用 Play 应用签名,这个密钥由 Google 管理;否则需要自己管理。
生成上传密钥
使用 Android Studio 生成
- 选择 Build → Generate Signed Bundle/APK
- 选择 Android App Bundle 或 APK,点击 Next
- 在 Key store path 下点击 Create new
- 填写信息:
密钥库:
- Key store path:选择保存位置,文件扩展名为
.jks - Password:创建安全密码
密钥:
- Alias:密钥标识名
- Password:密钥密码(建议与密钥库密码相同)
- Validity:有效期(建议至少 25 年)
- Certificate:证书信息(组织、城市等)
使用命令行生成
bash
keytool -genkey -v -keystore my-release-key.jks \
-alias my-key-alias \
-keyalg RSA \
-keysize 2048 \
-validity 10000配置签名
在 build.gradle 中配置
kotlin
android {
signingConfigs {
create("release") {
storeFile = file("../keystore/release.jks")
storePassword = "your-keystore-password"
keyAlias = "your-key-alias"
keyPassword = "your-key-password"
}
}
buildTypes {
getByName("release") {
signingConfig = signingConfigs.getByName("release")
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}groovy
android {
signingConfigs {
release {
storeFile file('../keystore/release.jks')
storePassword 'your-keystore-password'
keyAlias 'your-key-alias'
keyPassword 'your-key-password'
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}⚠️ 安全警告:不要将密码硬编码在构建文件中!
从环境变量读取密码
kotlin
android {
signingConfigs {
create("release") {
storeFile = file("../keystore/release.jks")
storePassword = System.getenv("KEYSTORE_PASSWORD")
keyAlias = System.getenv("KEY_ALIAS")
keyPassword = System.getenv("KEY_PASSWORD")
}
}
}groovy
android {
signingConfigs {
release {
storeFile file('../keystore/release.jks')
storePassword System.getenv('KEYSTORE_PASSWORD')
keyAlias System.getenv('KEY_ALIAS')
keyPassword System.getenv('KEY_PASSWORD')
}
}
}从 gradle.properties 读取
在项目根目录或用户目录的 gradle.properties 中配置:
properties
KEYSTORE_FILE=../keystore/release.jks
KEYSTORE_PASSWORD=your-keystore-password
KEY_ALIAS=your-key-alias
KEY_PASSWORD=your-key-password在 build.gradle(.kts) 中读取:
kotlin
android {
signingConfigs {
create("release") {
storeFile = file(project.property("KEYSTORE_FILE") as String)
storePassword = project.property("KEYSTORE_PASSWORD") as String
keyAlias = project.property("KEY_ALIAS") as String
keyPassword = project.property("KEY_PASSWORD") as String
}
}
}groovy
android {
signingConfigs {
release {
storeFile file(project.property('KEYSTORE_FILE'))
storePassword project.property('KEYSTORE_PASSWORD')
keyAlias project.property('KEY_ALIAS')
keyPassword project.property('KEY_PASSWORD')
}
}
}⚠️ 注意:将本地 gradle.properties 添加到 .gitignore。
为不同变体配置签名
kotlin
android {
signingConfigs {
create("debug") {
// 使用默认调试密钥
}
create("release") {
storeFile = file("release.jks")
storePassword = System.getenv("RELEASE_KEYSTORE_PASSWORD")
keyAlias = "release"
keyPassword = System.getenv("RELEASE_KEY_PASSWORD")
}
create("staging") {
storeFile = file("staging.jks")
storePassword = System.getenv("STAGING_KEYSTORE_PASSWORD")
keyAlias = "staging"
keyPassword = System.getenv("STAGING_KEY_PASSWORD")
}
}
buildTypes {
getByName("debug") {
signingConfig = signingConfigs.getByName("debug")
}
getByName("release") {
signingConfig = signingConfigs.getByName("release")
}
create("staging") {
signingConfig = signingConfigs.getByName("staging")
}
}
productFlavors {
create("demo") {
// Demo 使用 debug 签名
signingConfig = signingConfigs.getByName("debug")
}
create("full") {
// Full 使用 release 签名
signingConfig = signingConfigs.getByName("release")
}
}
}groovy
android {
signingConfigs {
debug {
// 使用默认调试密钥
}
release {
storeFile file('release.jks')
storePassword System.getenv('RELEASE_KEYSTORE_PASSWORD')
keyAlias 'release'
keyPassword System.getenv('RELEASE_KEY_PASSWORD')
}
staging {
storeFile file('staging.jks')
storePassword System.getenv('STAGING_KEYSTORE_PASSWORD')
keyAlias 'staging'
keyPassword System.getenv('STAGING_KEY_PASSWORD')
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
signingConfig signingConfigs.release
}
staging {
signingConfig signingConfigs.staging
}
}
productFlavors {
demo {
signingConfig signingConfigs.debug
}
full {
signingConfig signingConfigs.release
}
}
}查看签名信息
查看 APK 签名
bash
# 查看签名证书信息
keytool -printcert -jarfile app-release.apk
# 查看密钥库信息
keytool -list -v -keystore release.jks生成签名报告
在Android Studio 中:Build → Generate Signed Bundle/APK → View signing report
或使用 Gradle 任务:
bash
./gradlew signingReport输出示例:
Variant: release
Config: release
Store: /path/to/release.jks
Alias: release-key
MD5: A1:B2:C3:...
SHA1: D4:E5:F6:...
SHA-256: G7:H8:I9:...
Valid until: ...Play 应用签名
使用 Play 应用签名后,签名流程如下:
- 开发者使用上传密钥签名 AAB/APK
- 上传到 Google Play
- Google Play 验证上传密钥
- Google Play 使用应用签名密钥重新签名
- 用户下载使用应用签名密钥签名的 APK
优势:
- 上传密钥丢失可以重置
- 应用签名密钥由 Google 安全保管
- 支持 App Bundle 优化分发
密钥安全最佳实践
保护密钥库文件:
- 不要提交到版本控制系统
- 添加到
.gitignore - 安全备份(多个位置)
密码安全:
- 使用强密码
- 不要硬编码在代码中
- 使用环境变量或安全的密钥管理工具
CI/CD 环境:
- 使用加密的环境变量
- 限制访问权限
- 使用专用的构建密钥(非开发者个人密钥)
备份策略:
- 备份密钥库文件到安全位置
- 记录密码(保存在密码管理器中)
- 记录密钥别名和有效期
密钥丢失补救:
- 使用 Play 应用签名可以重置上传密钥
- 如果应用签名密钥丢失,无法更新应用(只能发布新应用)