使用 release key 对 LineageOS 进行编译和签名
版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/
为什么需要使用 release key
test-key 是一个公开的、众所周知的开发测试密钥,广泛用于测试阶段。这意味着任何人都可以获取这个密钥,并用它签署自己修改的 APK 或系统文件。
使用 test-key 签署的系统镜像通常无法通过 Google 的 CTS(兼容性测试套件)认证,Google Play 商店、Google 服务框架等应用可能无法正常运行,某些第三方应用(例如银行应用或数字版权管理应用)也可能拒绝在设备上运行。
OTA 更新包必须使用 Release Key 来签名。签名的更新包经过验证,只有具有相同 Release Key 的设备才能接收和安装更新。
生成 release key
执行 nano make_keys.sh 创建脚本,内容如下
subject='/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=linchaolong.dev@gmail.com'
# 创建 keys 目录(如果不存在)
mkdir -p keys
for cert in bluetooth cyngn-app media networkstack nfc platform releasekey sdk_sandbox shared testcert testkey verity; do \
./development/tools/make_key keys/$cert "$subject"; \
done
通过脚本创建 keys 目录并使用 make_key 命令生成你自己的密钥。
运行脚本生成密钥文件。
# 添加执行权限
chmod +x make_keys.sh
# 运行脚本
./make_keys.sh
为了避免密码解密的复杂性,生成一个未加密的私钥,防止签名过程提示输入密码。
Enter password for 'keys/bluetooth' (blank for none; password will be visible):
creating keys/bluetooth.pk8 with no password
Enter password for 'keys/cyngn-app' (blank for none; password will be visible):
creating keys/cyngn-app.pk8 with no password
Enter password for 'keys/media' (blank for none; password will be visible):
creating keys/media.pk8 with no password
Enter password for 'keys/networkstack' (blank for none; password will be visible):
creating keys/networkstack.pk8 with no password
Enter password for 'keys/nfc' (blank for none; password will be visible):
creating keys/nfc.pk8 with no password
Enter password for 'keys/platform' (blank for none; password will be visible):
creating keys/platform.pk8 with no password
Enter password for 'keys/releasekey' (blank for none; password will be visible):
creating keys/releasekey.pk8 with no password
Enter password for 'keys/sdk_sandbox' (blank for none; password will be visible):
creating keys/sdk_sandbox.pk8 with no password
Enter password for 'keys/shared' (blank for none; password will be visible):
creating keys/shared.pk8 with no password
Enter password for 'keys/testcert' (blank for none; password will be visible):
creating keys/testcert.pk8 with no password
Enter password for 'keys/testkey' (blank for none; password will be visible):
creating keys/testkey.pk8 with no password
Enter password for 'keys/verity' (blank for none; password will be visible):
creating keys/verity.pk8 with no password
生成的密钥都在 keys 目录下,每条命令会生成两个文件:一个 .x509.pem 公钥证书文件和一个 .pk8 私钥文件:
releasekey:主要用于签署系统中的所有 APK 文件,确保这些 APK 来自可信任的来源。
platform:签署系统框架和其他核心组件,确保这些组件未被篡改。
shared:用于签署需要跨应用共享 UID 的 APK,例如具有相同签名的应用可以共享数据。
media:专门用于签署与多媒体相关的 APK 文件。
networkstack:用于签署与网络堆栈相关的组件和应用,确保网络功能的安全性。
testkey:这是 Android 系统中的默认密钥,主要用于开发和测试环境下的签名,但不应在生产环境中使用。
cyngn-priv-app:可能与 CyanogenMod 或 LineageOS 特定的私有应用签名有关。
bluetooth:用于签署蓝牙服务或相关的 APK 文件。
sdk_sandbox:签署与 SDK 沙箱相关的应用或组件,确保开发环境的安全。
verity:用于签署与 Verified Boot 相关的组件,确保设备启动时的安全性。
ls keys
bluetooth.pk8 media.pk8 nfc.pk8 releasekey.pk8 shared.pk8 testkey.pk8
bluetooth.x509.pem media.x509.pem nfc.x509.pem releasekey.x509.pem shared.x509.pem testkey.x509.pem
cyngn-app.pk8 networkstack.pk8 platform.pk8 sdk_sandbox.pk8 testcert.pk8 verity.pk8
cyngn-app.x509.pem networkstack.x509.pem platform.x509.pem sdk_sandbox.x509.pem testcert.x509.pem verity.x509.pem
生成 target files
# 初始化编译环境
source build/envsetup.sh
# 设置构建目标
breakfast wayne
# 开始编译
mka target-files-package otatools
签名 target files
LineageOS 18.1 及以下版本的签名流程
sign_target_files_apks -o -d keys \
$OUT/obj/PACKAGING/target_files_intermediates/*-target_files-*.zip \
signed-target_files.zip
注意:对于早于 18.1 的 LineageOS 版本,您必须在 sign_target_files_apks 命令前添加 ./build/tools/releasetools/
./build/tools/releasetools/sign_target_files_apks -o -d keys \
$OUT/obj/PACKAGING/target_files_intermediates/*-target_files-*.zip \
signed-target_files.zip
LineageOS 19.1及以上版本的签名流程
sign_target_files_apks -o -d keys \
--extra_apks AdServicesApk.apk=keys/releasekey \
--extra_apks FederatedCompute.apk=keys/releasekey \
--extra_apks HalfSheetUX.apk=keys/releasekey \
--extra_apks HealthConnectBackupRestore.apk=keys/releasekey \
--extra_apks HealthConnectController.apk=keys/releasekey \
--extra_apks OsuLogin.apk=keys/releasekey \
--extra_apks SafetyCenterResources.apk=keys/releasekey \
--extra_apks ServiceConnectivityResources.apk=keys/releasekey \
--extra_apks ServiceUwbResources.apk=keys/releasekey \
--extra_apks ServiceWifiResources.apk=keys/releasekey \
--extra_apks WifiDialog.apk=keys/releasekey \
--extra_apks com.android.adbd.apex=keys/com.android.adbd \
--extra_apks com.android.adservices.apex=keys/com.android.adservices \
--extra_apks com.android.adservices.api.apex=keys/com.android.adservices.api \
--extra_apks com.android.appsearch.apex=keys/com.android.appsearch \
--extra_apks com.android.art.apex=keys/com.android.art \
--extra_apks com.android.bluetooth.apex=keys/com.android.bluetooth \
--extra_apks com.android.btservices.apex=keys/com.android.btservices \
--extra_apks com.android.cellbroadcast.apex=keys/com.android.cellbroadcast \
--extra_apks com.android.compos.apex=keys/com.android.compos \
--extra_apks com.android.configinfrastructure.apex=keys/com.android.configinfrastructure \
--extra_apks com.android.connectivity.resources.apex=keys/com.android.connectivity.resources \
--extra_apks com.android.conscrypt.apex=keys/com.android.conscrypt \
--extra_apks com.android.devicelock.apex=keys/com.android.devicelock \
--extra_apks com.android.extservices.apex=keys/com.android.extservices \
--extra_apks com.android.graphics.pdf.apex=keys/com.android.graphics.pdf \
--extra_apks com.android.hardware.biometrics.face.virtual.apex=keys/com.android.hardware.biometrics.face.virtual \
--extra_apks com.android.hardware.biometrics.fingerprint.virtual.apex=keys/com.android.hardware.biometrics.fingerprint.virtual \
--extra_apks com.android.hardware.boot.apex=keys/com.android.hardware.boot \
--extra_apks com.android.hardware.cas.apex=keys/com.android.hardware.cas \
--extra_apks com.android.hardware.wifi.apex=keys/com.android.hardware.wifi \
--extra_apks com.android.healthfitness.apex=keys/com.android.healthfitness \
--extra_apks com.android.hotspot2.osulogin.apex=keys/com.android.hotspot2.osulogin \
--extra_apks com.android.i18n.apex=keys/com.android.i18n \
--extra_apks com.android.ipsec.apex=keys/com.android.ipsec \
--extra_apks com.android.media.apex=keys/com.android.media \
--extra_apks com.android.media.swcodec.apex=keys/com.android.media.swcodec \
--extra_apks com.android.mediaprovider.apex=keys/com.android.mediaprovider \
--extra_apks com.android.nearby.halfsheet.apex=keys/com.android.nearby.halfsheet \
--extra_apks com.android.networkstack.tethering.apex=keys/com.android.networkstack.tethering \
--extra_apks com.android.neuralnetworks.apex=keys/com.android.neuralnetworks \
--extra_apks com.android.ondevicepersonalization.apex=keys/com.android.ondevicepersonalization \
--extra_apks com.android.os.statsd.apex=keys/com.android.os.statsd \
--extra_apks com.android.permission.apex=keys/com.android.permission \
--extra_apks com.android.resolv.apex=keys/com.android.resolv \
--extra_apks com.android.rkpd.apex=keys/com.android.rkpd \
--extra_apks com.android.runtime.apex=keys/com.android.runtime \
--extra_apks com.android.safetycenter.resources.apex=keys/com.android.safetycenter.resources \
--extra_apks com.android.scheduling.apex=keys/com.android.scheduling \
--extra_apks com.android.sdkext.apex=keys/com.android.sdkext \
--extra_apks com.android.support.apexer.apex=keys/com.android.support.apexer \
--extra_apks com.android.telephony.apex=keys/com.android.telephony \
--extra_apks com.android.telephonymodules.apex=keys/com.android.telephonymodules \
--extra_apks com.android.tethering.apex=keys/com.android.tethering \
--extra_apks com.android.tzdata.apex=keys/com.android.tzdata \
--extra_apks com.android.uwb.apex=keys/com.android.uwb \
--extra_apks com.android.uwb.resources.apex=keys/com.android.uwb.resources \
--extra_apks com.android.virt.apex=keys/com.android.virt \
--extra_apks com.android.vndk.current.apex=keys/com.android.vndk.current \
--extra_apks com.android.vndk.current.on_vendor.apex=keys/com.android.vndk.current.on_vendor \
--extra_apks com.android.wifi.apex=keys/com.android.wifi \
--extra_apks com.android.wifi.dialog.apex=keys/com.android.wifi.dialog \
--extra_apks com.android.wifi.resources.apex=keys/com.android.wifi.resources \
--extra_apks com.google.pixel.camera.hal.apex=keys/com.google.pixel.camera.hal \
--extra_apks com.google.pixel.vibrator.hal.apex=keys/com.google.pixel.vibrator.hal \
--extra_apks com.qorvo.uwb.apex=keys/com.qorvo.uwb \
--extra_apex_payload_key com.android.adbd.apex=keys/com.android.adbd.pem \
--extra_apex_payload_key com.android.adservices.apex=keys/com.android.adservices.pem \
--extra_apex_payload_key com.android.adservices.api.apex=keys/com.android.adservices.api.pem \
--extra_apex_payload_key com.android.appsearch.apex=keys/com.android.appsearch.pem \
--extra_apex_payload_key com.android.art.apex=keys/com.android.art.pem \
--extra_apex_payload_key com.android.bluetooth.apex=keys/com.android.bluetooth.pem \
--extra_apex_payload_key com.android.btservices.apex=keys/com.android.btservices.pem \
--extra_apex_payload_key com.android.cellbroadcast.apex=keys/com.android.cellbroadcast.pem \
--extra_apex_payload_key com.android.compos.apex=keys/com.android.compos.pem \
--extra_apex_payload_key com.android.configinfrastructure.apex=keys/com.android.configinfrastructure.pem \
--extra_apex_payload_key com.android.connectivity.resources.apex=keys/com.android.connectivity.resources.pem \
--extra_apex_payload_key com.android.conscrypt.apex=keys/com.android.conscrypt.pem \
--extra_apex_payload_key com.android.devicelock.apex=keys/com.android.devicelock.pem \
--extra_apex_payload_key com.android.extservices.apex=keys/com.android.extservices.pem \
--extra_apex_payload_key com.android.graphics.pdf.apex=keys/com.android.graphics.pdf.pem \
--extra_apex_payload_key com.android.hardware.biometrics.face.virtual.apex=keys/com.android.hardware.biometrics.face.virtual.pem \
--extra_apex_payload_key com.android.hardware.biometrics.fingerprint.virtual.apex=keys/com.android.hardware.biometrics.fingerprint.virtual.pem \
--extra_apex_payload_key com.android.hardware.boot.apex=keys/com.android.hardware.boot.pem \
--extra_apex_payload_key com.android.hardware.cas.apex=keys/com.android.hardware.cas.pem \
--extra_apex_payload_key com.android.hardware.wifi.apex=keys/com.android.hardware.wifi.pem \
--extra_apex_payload_key com.android.healthfitness.apex=keys/com.android.healthfitness.pem \
--extra_apex_payload_key com.android.hotspot2.osulogin.apex=keys/com.android.hotspot2.osulogin.pem \
--extra_apex_payload_key com.android.i18n.apex=keys/com.android.i18n.pem \
--extra_apex_payload_key com.android.ipsec.apex=keys/com.android.ipsec.pem \
--extra_apex_payload_key com.android.media.apex=keys/com.android.media.pem \
--extra_apex_payload_key com.android.media.swcodec.apex=keys/com.android.media.swcodec.pem \
--extra_apex_payload_key com.android.mediaprovider.apex=keys/com.android.mediaprovider.pem \
--extra_apex_payload_key com.android.nearby.halfsheet.apex=keys/com.android.nearby.halfsheet.pem \
--extra_apex_payload_key com.android.networkstack.tethering.apex=keys/com.android.networkstack.tethering.pem \
--extra_apex_payload_key com.android.neuralnetworks.apex=keys/com.android.neuralnetworks.pem \
--extra_apex_payload_key com.android.ondevicepersonalization.apex=keys/com.android.ondevicepersonalization.pem \
--extra_apex_payload_key com.android.os.statsd.apex=keys/com.android.os.statsd.pem \
--extra_apex_payload_key com.android.permission.apex=keys/com.android.permission.pem \
--extra_apex_payload_key com.android.resolv.apex=keys/com.android.resolv.pem \
--extra_apex_payload_key com.android.rkpd.apex=keys/com.android.rkpd.pem \
--extra_apex_payload_key com.android.runtime.apex=keys/com.android.runtime.pem \
--extra_apex_payload_key com.android.safetycenter.resources.apex=keys/com.android.safetycenter.resources.pem \
--extra_apex_payload_key com.android.scheduling.apex=keys/com.android.scheduling.pem \
--extra_apex_payload_key com.android.sdkext.apex=keys/com.android.sdkext.pem \
--extra_apex_payload_key com.android.support.apexer.apex=keys/com.android.support.apexer.pem \
--extra_apex_payload_key com.android.telephony.apex=keys/com.android.telephony.pem \
--extra_apex_payload_key com.android.telephonymodules.apex=keys/com.android.telephonymodules.pem \
--extra_apex_payload_key com.android.tethering.apex=keys/com.android.tethering.pem \
--extra_apex_payload_key com.android.tzdata.apex=keys/com.android.tzdata.pem \
--extra_apex_payload_key com.android.uwb.apex=keys/com.android.uwb.pem \
--extra_apex_payload_key com.android.uwb.resources.apex=keys/com.android.uwb.resources.pem \
--extra_apex_payload_key com.android.virt.apex=keys/com.android.virt.pem \
--extra_apex_payload_key com.android.vndk.current.apex=keys/com.android.vndk.current.pem \
--extra_apex_payload_key com.android.vndk.current.on_vendor.apex=keys/com.android.vndk.current.on_vendor.pem \
--extra_apex_payload_key com.android.wifi.apex=keys/com.android.wifi.pem \
--extra_apex_payload_key com.android.wifi.dialog.apex=keys/com.android.wifi.dialog.pem \
--extra_apex_payload_key com.android.wifi.resources.apex=keys/com.android.wifi.resources.pem \
--extra_apex_payload_key com.google.pixel.camera.hal.apex=keys/com.google.pixel.camera.hal.pem \
--extra_apex_payload_key com.google.pixel.vibrator.hal.apex=keys/com.google.pixel.vibrator.hal.pem \
--extra_apex_payload_key com.qorvo.uwb.apex=keys/com.qorvo.uwb.pem \
$OUT/obj/PACKAGING/target_files_intermediates/*-target_files*.zip \
signed-target_files.zip
生成安装包
ota_from_target_files -k keys/releasekey \
--block --backup=true \
signed-target_files.zip \
signed-ota_update.zip
注意:对于早于 18.1 的 LineageOS 版本,必须在 ota_from_target_files 命令前添加 ./build/tools/releasetools/
./build/tools/releasetools/ota_from_target_files -k keys/releasekey \
--block --backup=true \
signed-target_files.zip \
signed-ota_update.zip
执行完成后,在当前目录下生成的 signed-ota_update.zip 就是签名后的刷机包
Android.bp android.ipr~ build external libnativehelper pdk signed-target_files.zip
Makefile android.iws cts frameworks lineage platform_testing system
android art dalvik hardware lineage-sdk prebuilts test
android.iml bionic developers kernel make_keys.sh sdk toolchain
android.iml~ bootable development keys out sign_ota_wayne.sh tools
android.ipr bootstrap.bash device libcore packages signed-ota_update.zip vendor
自动化脚本
以 LineageOS17.1(wayne) 为例,nano sign_ota_wayne.sh 创建脚本,内容如下
source build/envsetup.sh
# 设置构建目标
breakfast wayne
# target files
mka target-files-package otatools
# sign target files
./build/tools/releasetools/sign_target_files_apks -o -d keys \
$OUT/obj/PACKAGING/target_files_intermediates/*-target_files-*.zip \
signed-target_files.zip
# sign ota package
./build/tools/releasetools/ota_from_target_files -k keys/releasekey \
--block --backup=true \
signed-target_files.zip \
signed-ota_update.zip
通过脚本把生成自定义签名安装包的流程自动化。
# 添加执行权限
chmod +x signing_ota_wayne.sh
# 执行脚本
./sign_ota_wayne.sh
刷机
进入recovery模式(或者同时按住【音量+】和【开机键】)
fastboot reboot recovery
注意:如果目前设备安装包签名和现在刷的安装包不一样,需要格式化 system 分区。格式化流程:【Factory reset】【Format system partition】。
【Apply update】【Apply from adb】开启 adb sideload
开始刷机
adb sideload E:\lineageos\signed-ota_update.zip
等待刷机完成重启系统。
参考: Signing Builds