首先我们需要在源代码环境中将 build/target/product/security/ 文件夹 copy 到本地。
下边的操作需要在 ubuntu 或者 mac 下。
重要安全提醒:
platform
密钥是系统级私钥,拥有它就能签出系统权限应用。不要把它放到公共机器 / 共享位置,谨慎保管,必要时改密码并限制访问。
1) 先看看文件格式(确认 pk8 是二进制还是 PEM)
file platform.pk8
# 或
head -n 3 platform.pk8
- 如果看到
-----BEGIN
开头,那就是 PEM 格式私钥(可以直接用)。 - 如果是二进制(比如
data
/DER
),需要先把它转换成 PEM。
2)(如果需要)把 platform.pk8
转成 PEM 私钥
仅当 platform.pk8
不是 PEM(即是 DER/PKCS8 二进制)时运行:
openssl pkcs8 -in platform.pk8 -inform DER -out platform.key.pem -nocrypt
如果 platform.pk8
已经是 PEM,就把它重命名/复制为 platform.key.pem
:
cp platform.pk8 platform.key.pem
3) 用证书 + 私钥 导出 PKCS#12(.p12)
把 cert 和私钥合成一个 .p12(后面用 keytool 导入到 JKS):
openssl pkcs12 -export \-inkey platform.key.pem \-in platform.x509.pem \-name platform \-out platform.p12
- 上面会提示你设置一个导出密码(
Export Password
)。记住它,后面导入时需要(示例中我们用p12pass
说明,运行时请用安全密码)。
如果你想在命令行里直接设置密码(不建议在公共 shell 历史中出现),可以:
openssl pkcs12 -export -inkey platform.key.pem -in platform.x509.pem -name platform -out platform.p12 -passout pass:p12pass
4) 把 PKCS#12 导入 Java Keystore(.jks)
用 keytool
将 .p12
转成 platform.jks
:
keytool -importkeystore \-deststorepass android \-destkeypass android \-destkeystore platform.jks \-srckeystore platform.p12 \-srcstoretype PKCS12 \-srcstorepass p12pass \-alias platform
- 这里
-deststorepass
/-destkeypass
我示例用了android
(方便演示),实际请用强密码替换。 -srcstorepass
要填第 3 步时你设的导出密码(上例是p12pass
)。
5) 验证 keystore 内容
keytool -list -v -keystore platform.jks -storepass android
输出里应该能看到 alias platform
,以及证书信息(Subject/Issuer/有效期等)。若看到就成功了。
6) 用 platform.jks 给 APK 签名(示例:apksigner)
建议用 apksigner
(Android build tools 提供):
# 使用 apksigner(Android build-tools >= 24)
apksigner sign --ks platform.jks --ks-pass pass:android --ks-key-alias platform app-system-signed.apk
或者用 jarsigner
(旧法):
jarsigner -keystore platform.jks -storepass android -keypass android app-release-unsigned.apk platform
然后最好用 zipalign
(如果是最终安装包)和 apksigner verify
验证签名:
# zipalign (android sdk build-tools)
zipalign -v 4 app-release-unsigned.apk app-aligned.apk
apksigner verify --verbose --print-certs app-aligned.apk
额外说明(常见问题)
- 如果
openssl pkcs12
报错 “Mac verify error:invalid password?”:说明你提供的-passout
/交互密码不匹配,重试并确认密码。 - 如果
platform.pk8
是加密私钥(很少见),需要先用 openssl 解密(需要原始密码)。 - 系统签名要求与 ROM 中的
platform.x509.pem
/platform.pk8
一致:如果你用的是源码树同目录下的 key,那么在制作系统镜像时签名一致,App 能拿到android:sharedUserId="android.uid.system"
/signature|system
等特权。 - 如果你只是本地测试并不想替换设备系统的 platform key,更安全的做法是在自建的测试 ROM 中使用该 key 签名或把签名后的 apk 放到
/system/priv-app/
并设置正确权限。直接在俗称的“普通设备”上用 platform key 安装可能受系统限制(厂商 ROM 与密钥不同)。
简短命令总览(一键版,假设 pk8 为二进制)
# 转成 PEM(如果已经是 PEM 可跳过)
openssl pkcs8 -in platform.pk8 -inform DER -out platform.key.pem -nocrypt# 导出 p12(会询问导出密码)
openssl pkcs12 -export -inkey platform.key.pem -in platform.x509.pem -name platform -out platform.p12# 导入到 JKS(示例密码:android / p12pass,实际请换强密码)
keytool -importkeystore -deststorepass android -destkeypass android -destkeystore platform.jks \-srckeystore platform.p12 -srcstoretype PKCS12 -srcstorepass p12pass -alias platform# 验证
keytool -list -v -keystore platform.jks -storepass android
如何将 jks 文件导入到项目的gradle中?
1. 放置位置
常规做法是把 platform.jks
放在工程目录下的某个子目录(例如 app/keystore/platform.jks
),不要放进版本控制,只在本地或 CI 构建机上保管。
2. 配置 gradle.properties
(推荐)
在项目根目录的 gradle.properties
中写上 keystore 信息(可以避免明文写在 build.gradle
里):
MY_KEYSTORE=app/keystore/platform.jks
MY_KEYSTORE_PASSWORD=android
MY_KEY_ALIAS=platform
MY_KEY_PASSWORD=android
这里密码要替换成你创建 jks 时设定的。
3. 配置 app/build.gradle
→ signingConfigs
android {signingConfigs {platform {storeFile file(MY_KEYSTORE)storePassword MY_KEYSTORE_PASSWORDkeyAlias MY_KEY_ALIASkeyPassword MY_KEY_PASSWORD}}buildTypes {release {signingConfig signingConfigs.platformminifyEnabled falseshrinkResources false}debug {// 如果需要调试也走 platform 签名(一般系统 App 要这样)signingConfig signingConfigs.platform}}
}
4. 构建 & 签名
这样执行 ./gradlew assembleRelease
就会自动用你 platform.jks
里的 key 来签名 APK。
5. 额外提醒 ⚠️
- 普通设备上安装不了:因为你拿到的
platform
key 跟设备出厂的 system.img 里用的不一样,只有在你自己编的系统(刷机)里,才能识别为“系统签名”。 - 真机系统 App 场景:如果你控制了固件(比如手表项目),就可以在同一套 key 下签 ROM 和 APK,这样 Gradle 打出来的包就能拥有系统签名权限(例如
android:sharedUserId="android.uid.system"
或signature|system
权限)。 - 密钥最好不要随项目源码走,建议本地配置或 CI 配置注入。