对要发布的编译版本进行签名

Android OS 映像在两个地方使用加密签名:

  1. 映像中的所有 .apk 文件都必须经过签名。Android 软件包管理器通过下列两种方式使用 .apk 签名:

    • 更换应用时,必须使用与旧应用相同的密钥对其签名,才能存取旧应用的数据。无论是通过覆盖 .apk 来更新用户应用,还是使用安装在 /data 下的新版本应用来覆盖系统应用,这一点都适用。
    • 如果两个或多个应用想要共享同一个用户 ID(方便共享数据等),则必须使用相同的密钥对它们进行签名。
  2. 必须使用符合系统预期的密钥对 OTA 更新包进行签名,否则在安装过程中 OTA 更新包将被拒绝。

发布密钥

Android 树的 build/target/product/security 目录中提供了测试密钥。使用 make 编译 Android OS 映像便可使用这些测试密钥对所有 .apk 文件进行签名。由于这些测试密钥是公开的,任何人都可以使用相同的密钥对他们自己的 .apk 文件签名,这样他们就能够替换或盗用您的操作系统映像中编译的系统应用。因此,您必须使用只有您自己才能访问的特殊“发布密钥”集对公开发布或部署的 Android OS 映像进行签名。

要生成您自己的唯一发布密钥集,请在 Android 树的根目录下运行以下命令:

subject='/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com' mkdir ~/.android-certs for x in releasekey platform shared media; do \ ./development/tools/make_key ~/.android-certs/$x "$subject"; \ done

您需要对 $subject 进行更改以反映贵组织的信息。您可以使用任何目录,但要注意选择一个已备份且安全的位置。部分供应商会使用强密码加密私钥,并将其存储在源代码控制系统中;其他供应商则将他们的发布密钥完全存储在其他地方,如气隙阻隔的计算机上。

要生成发布映像,请使用以下命令:

make dist ./build/tools/releasetools/sign_target_files_apks \ -o \ # explained in the next section -d ~/.android-certs out/dist/*-target_files-*.zip \ signed-target_files.zip

sign_target_files_apks 脚本将目标文件 .zip 作为输入文件,并生成一个新的目标文件 .zip,其中所有的 .apk 都已使用新密钥签名。您可以在 signed-target_files.zip 中的 IMAGES/ 目录下找到新签名的映像。

对 OTA 更新包进行签名

您可以按照以下步骤将已签名的目标文件 zip 转换为已签名的 OTA 更新 zip:

./build/tools/releasetools/ota_from_target_files \ -k ~/.android-certs/releasekey \ signed-target_files.zip \ signed-ota_update.zip

签名和旁加载

旁加载不会绕过 Recovery 流程中的正常软件包签名验证机制。在安装一个软件包之前,Recovery 会验证该软件包是否由与 Recovery 分区中存储的公钥相匹配的私钥进行签名,这与利用无线方式传输的软件包的处理方式一样。

从主系统收到的更新包通常要经过两次验证:一次是由主系统使用 Android API 中的 RecoverySystem.verifyPackage() 方法进行验证,另一次是通过 Recovery 进行验证。RecoverySystem API 对照存储在主系统 /system/etc/security/otacerts.zip 文件(默认情况下)中的公钥对签名进行检查。Recovery 对照存储在 Recovery 分区 RAM 磁盘中的 /res/keys 文件中的公钥对签名进行检查。

默认情况下,由此版本生成的目标文件 .zip 会将 OTA 证书设置为与测试密钥相匹配。在发布的映像上,必须使用不同的证书,这样设备才能验证更新包的真实性。如前面一部分所示,将 -o 标志传递到 sign_target_files_apks 即可将测试密钥证书替换成您的证书目录中的发布密钥证书。

通常情况下,系统映像和 Recovery 映像存储的是相同的 OTA 公钥集。通过将密钥仅添加至 Recovery 密钥集,可对只能通过旁加载安装的 apk 包(假设主系统的更新下载机制正确地对照 otacerts.zip 进行验证)签名。您可以通过在产品定义中设置 PRODUCT_EXTRA_RECOVERY_KEYS 变量来指定其他仅可纳入 Recovery 中的密钥:

vendor/yoyodyne/tardis/products/tardis.mk

[...] PRODUCT_EXTRA_RECOVERY_KEYS := vendor/yoyodyne/security/tardis/sideload

其中包括 Recovery 密钥文件中的公钥 vendor/yoyodyne/security/tardis/sideload.x509.pem,因此它可以安装用此公钥签名的 apk 包。但 otacerts.zip 中不包含额外的密钥,因此正确验证下载包的系统不会针对用此密钥签名的 apk 包调用 Recovery。

证书和私钥

每个密钥都包含两个文件:一个是扩展名为 .x509.pem 的证书,另一个是扩展名为 .pk8 的私钥。私钥需要加以保密,并用于对 apk 包进行签名。密钥本身也可能受密码保护。相比之下,证书只包含公开的一半密钥,因此可以大范围地分发。证书被用于验证某个 apk 包是否由相应的私钥进行签名。

标准 Android 版本使用四个密钥,所有这些密钥都位于 build/target/product/security 中:

testkey

适用于未另外指定密钥的 apk 包的通用默认密钥。

平台

适用于核心平台所包含的 apk 包的测试密钥。

共享

适用于家庭/联系人进程中的共享内容的测试密钥。

媒体

适用于媒体/下载系统所包含的 apk 包的测试密钥。

单个 apk 包通过在其 Android.mk 文件中设置 LOCAL_CERTIFICATE 来指定其中一个密钥。(如果未设置此变量,则使用 testkey。)您还可以通过路径名指定完全不同的密钥,例如:

device/yoyodyne/apps/SpecialApp/Android.mk

[...] LOCAL_CERTIFICATE := device/yoyodyne/security/special

现在,此版本使用 device/yoyodyne/security/special.{x509.pem,pk8} 密钥来对 SpecialApp.apk 进行签名。此版本仅可使用不受密码保护的私钥。

高级签名选项

当您运行 sign_target_files_apks 脚本时,必须在命令行中指定在编译版本中使用的每个密钥的替换密钥。-ksrc_key= dest_key 标记每次只能指定一个替换密钥。-d dir 标记可让您指定一个包含四个密钥(可替换 build/target/product/security 中的所有相应密钥)的目录;这相当于使用四次 -k 来指定相应的映射:

build/target/product/security/testkey = dir/releasekey build/target/product/security/platform = dir/platform build/target/product/security/shared = dir/shared build/target/product/security/media = dir/media

对于假定的 tardis 产品,您需要五个受密码保护的密钥:四个用于替换 build/target/product/security 中的四个密钥,其余一个则用于替换 SpecialApp 所需的另外一个 keydevice/yoyodyne/security/special(请参见上面的示例)。如果密钥位于以下文件中:

vendor/yoyodyne/security/tardis/releasekey.x509.pem vendor/yoyodyne/security/tardis/releasekey.pk8 vendor/yoyodyne/security/tardis/platform.x509.pem vendor/yoyodyne/security/tardis/platform.pk8 vendor/yoyodyne/security/tardis/shared.x509.pem vendor/yoyodyne/security/tardis/shared.pk8 vendor/yoyodyne/security/tardis/media.x509.pem vendor/yoyodyne/security/tardis/media.pk8 vendor/yoyodyne/security/special.x509.pem vendor/yoyodyne/security/special.pk8 # NOT password protected vendor/yoyodyne/security/special-release.x509.pem vendor/yoyodyne/security/special-release.pk8 # password protected

那么您将对所有应用签名,如下所示:

./build/tools/releasetools/sign_target_files_apks -d vendor/yoyodyne/security/tardis -k vendor/yoyodyne/special=vendor/yoyodyne/special-release -o tardis-target_files.zip signed-tardis-target_files.zip

此时会显示以下内容:

Enter password for vendor/yoyodyne/security/special-release key> Enter password for vendor/yoyodyne/security/tardis/media key> Enter password for vendor/yoyodyne/security/tardis/platform key> Enter password for vendor/yoyodyne/security/tardis/releasekey key> Enter password for vendor/yoyodyne/security/tardis/shared key> signing: Phone.apk (vendor/yoyodyne/security/tardis/platform) signing: Camera.apk (vendor/yoyodyne/security/tardis/media) signing: Special.apk (vendor/yoyodyne/security/special-release) signing: Email.apk (vendor/yoyodyne/security/tardis/releasekey) [...] signing: ContactsProvider.apk (vendor/yoyodyne/security/tardis/shared) signing: Launcher.apk (vendor/yoyodyne/security/tardis/shared) rewriting SYSTEM/build.prop: replace: ro.build.description=tardis-user Eclair ERC91 15449 test-keys with: ro.build.description=tardis-user Eclair ERC91 15449 release-keys replace: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/test-keys with: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/release-keys signing: framework-res.apk (vendor/yoyodyne/security/tardis/platform) rewriting RECOVERY/RAMDISK/default.prop: replace: ro.build.description=tardis-user Eclair ERC91 15449 test-keys with: ro.build.description=tardis-user Eclair ERC91 15449 release-keys replace: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/test-keys with: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/release-keys using: vendor/yoyodyne/security/tardis/releasekey.x509.pem for OTA package verification done.

在提示用户输入所有受密码保护的密钥的密码后,脚本会使用发布密钥对输入目标 .zip 中的所有 .apk 文件重新签名。在运行该命令之前,您还可以将 ANDROID_PW_FILE 环境变量设置为临时文件名;然后脚本会调用您的编辑器,允许您输入所有密钥的密码(采用该方式输入密码可能较为简便)。

sign_target_files_apks 还会在版本属性文件中重写版本描述和指纹,表明这是一个已签名的版本。-t 标志可以控制对指纹所做的编辑。使用 -h 运行脚本来查看所有标志上的文档。

手动生成密钥

Android 使用公开指数为 3 的 2048 位 RSA 密钥。您可以使用 openssl.org 提供的 openssl 工具来生成证书/私钥对:

# generate RSA key openssl genrsa -3 -out temp.pem 2048 Generating RSA private key, 2048 bit long modulus ....+++ .....................+++ e is 3 (0x3) # create a certificate with the public part of the key openssl req -new -x509 -key temp.pem -out releasekey.x509.pem -days 10000 -subj '/C=US/ST=California/L=San Narciso/O=Yoyodyne, Inc./OU=Yoyodyne Mobility/CN=Yoyodyne/emailAddress=yoyodyne@example.com' # create a PKCS#8-formatted version of the private key openssl pkcs8 -in temp.pem -topk8 -outform DER -out releasekey.pk8 -nocrypt # securely delete the temp.pem file shred --remove temp.pem

上述 openssl pkcs8 命令可创建一个适用于该版本系统的 .pk8 文件,该文件未设置密码。要创建一个带有密码保护的 .pk8 文件(您应当为所有实际的发布密钥执行此步骤),请将 -nocrypt 参数替换为 -passout stdin;这样 openssl 将使用从标准输入中读取的密码来加密私钥。该过程中不会输出任何提示。因此,当系统确实只是在等待您输入密码时,如果 stdin 是终端,程序将会处于挂起状态。可以对 Passout 参数使用其他值,以便从其他位置读取密码;有关详情,请参阅 openssl 文档。

temp.pem 中间文件包含不受任何类型的密码保护的私钥,因此在生成发布密钥时应谨慎处理该文件。需要特别指出的是,GNUshred 实用程序可能对网络或日志文件系统无效。在生成密钥时,您可以使用位于 RAM 磁盘(如 tmpfs 分区)中的工作目录以确保中间文件不会无意间被暴露。

创建映像文件

一旦您签署了目标文件 .zip,您便需要创建映像,以便将其存放到设备上。要从目标文件中创建已签名的映像,请在 Android 树形结构的根目录下运行以下命令:

./build/tools/releasetools/img_from_target_files signed-target-files.zip signed-img.zip 生成的文件 signed-img.zip 中包含所有 .img 文件。 要将映像加载到设备上,请使用 fastboot,如下所示:

fastboot update signed-img.zip

Android 系统(231)--OTA对要发布的编译版本进行签名相关推荐

  1. 【Android 逆向】修改运行中的 Android 进程的内存数据 ( Android 系统中调试器进程内存流程 | 编译内存调试动态库以及调试程序 )

    文章目录 一.Android 系统中调试器进程内存流程 二.编译内存调试动态库以及调试程序 三.博客资源 一.Android 系统中调试器进程内存流程 修改游戏运行中的内存 , 游戏运行之后 , 游戏 ...

  2. Android系统移植与调试之-------Amlogic方案编译步骤

    1. 拷贝Amlogic的SourceCode 切换目录到  /home/roco/work/amlogic/SourceCode/mx0831-0525下将mx0831-0525.tgz拷贝到  / ...

  3. android 测试工程 关闭混淆,混淆Android Test项目以及项目(在发布和混淆版本上运行测试)...

    在阅读赏金的评论之后,我意识到OP实际上只是提出了一些简单的是/否回复,所以我将把我的评论扩展到答案.一般来说,正确设计的proguard.cfg和项目结构足以防止这种困境. 典型的proguard配 ...

  4. android系统9.0的设计风格,携安卓P版本首发 华为EMUI9.0系统解析

    [TechWeb]8月28日,华为官方开启了华为+荣耀9款机型EMUI9.0 Beta版升级内测招募.9月5日,华为消费者BG在国内首次发布了基于Android P版本的EMUI9.0版本.10月份, ...

  5. android系统用在什么电脑,手机变电脑的简单操作 适用于所有Android系统的向日葵...

    现如今,什么电子设备对于我们来说最重要呢?毫无疑问,必定是人手一部不离不弃的手机!不过,可能有"杠精"会说了,电脑不是更重要?毕竟办公离不开,还有很多大型网络游戏也只能在电脑上才享 ...

  6. Android系统简介

    一.Android系统的前世今生 目前全球智能手机最主要的两大阵营是Android和IOS,Android和IOS是移动操作系统的名称,它们背后的公司是谷歌和苹果,所以有时候也叫做谷歌系统和苹果系统. ...

  7. 【Android从零单排系列一】《Android系统发展史》

    目录 前言 一.Android 创始人 二.Android 发展历程 三.Android各版本发布时间及特性 1.AndroidBeta:阿童木 2.Android 1.0:发条机器人 3.Andro ...

  8. android otaupdate源码路径,Android学习之OTA Update

    之前需要处理一些应用程序用到的update相关问题, 了解到android build system会利用开源的bsdiff进行一些关于package的更新动作. 这篇文章就分析一下android系统 ...

  9. Android系统编译小总结

    Android系统编译 简介 搭建编译环境 系统编译命令 常见小知识点 Android编译版本 Android.mk文件 编译系统中的变量和宏 native layer 编译碰到的问题 安装lib32 ...

最新文章

  1. nginx特定的 404页面利于seo
  2. unix oracle控制台,Linux平台下启动oracle11gEM控制台
  3. SVN 服务器发送了意外的返回值(405 Method Not Allowed),在响应 “MKCOL” 的请求
  4. 大学加权平均分计算器_英国排名前20的大学GPA要求
  5. javaweb学习总结(三十九):数据库连接池
  6. ioctl之FIONREAD
  7. 无服务器革命:好,坏和丑
  8. tomcat的jdbc连接池PoolExhaustedException 1
  9. matlab中提示错误使用* BLAS loading error解决方法
  10. Atitit 提升可读性sql subquery udf 子查询 目录 1. 使用udf 和参数@简化join和subquery 1 1.1.1. 子查询分类 1 2. 2.1 按返回结果集分类
  11. 常见查找算法之—二分查找
  12. Linux下通过ssh上传下载文件
  13. 黑马程序员--黑马程序员的入学流程真的“很黑”
  14. CTF-misc练习(https://buuoj.cn)之第二页
  15. 最好的开源网络入侵检测工具(网址及版本已验证并更新)
  16. sqlserver中执行顺序、TOP、PERCENT百分比、DISTINCT去掉重复值
  17. 李宏毅机器学习课程自测练习题
  18. Python的PIL库中的getpixel方法 putpixel方法
  19. 51NOD - 1677treecnt
  20. seetaface6 GPU版本windows编译

热门文章

  1. 【蓝桥杯单片机】Led+蜂鸣器+继电器
  2. (13)拨云见日,闲聊哈希表
  3. HTTP协议 (四) 缓存
  4. Java虚拟机 —— 内存和线程
  5. cx_Oracle模块
  6. [书摘]架构真经--可扩展性规则的利益与优先级排行榜
  7. 团队开发里频繁使用 git rebase 来保持树的整洁好吗?
  8. centos 搭建web平台
  9. 2015 HUAS Provincial Select Contest #2~C
  10. uva861 Little Bishops