Android操作系统映像在两个地方使用加密签名:.apk和/data。发布密钥存储在build/target/product/securitymake.apk中。要生成您自己的唯一发布密钥集,请在Android树的根目录下运行以下命令:

```bash

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 networkstack; do \n ./development/tools/make_key ~/.android-certs/$x "$subject"; \ndone

$subject

```

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

```bash

make dist

sign_target_files_apks \n -o \n # explained in the next section --default_key_mappings ~/.android-certs \n out/dist/*-target_files-*.zip \n signed-target_files.zip

sign_target_files_apks.zip.zip.apksigned-target_files.zipIMAGES/

```

对OTA软件包进行签名时,您可以按照以下步骤将已签名的目标文件zip转换为已签名的OTA更新zip:

```bash

ota_from_target_files \n -k (--package_key) \n signed-target_files.zip \n signed-ota_update.zip

```

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

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

```makefile

vendor/yoyodyne/tardis/products/tardis.mk

[...]

PRODUCT_EXTRA_RECOVERY_KEYS := vendor/yoyodyne/security/tardis/sideload

vendor/yoyodyne/security/tardis/sideload.x509.pem

证书和私钥

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

build/target/product/security

testkey

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

```

平台、共享、媒体、网络stack等不同类型的测试密钥:

```makefile

platform

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

shared

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

media

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

networkstack

适用于网络系统所包含的 apk 包的测试密钥。networkstack 密钥用于为设计为模块化系统组件的二进制文件签名。如果您的模块更新是单独构建的,并且以预构建的形式集成到设备映像中,您可能就不需要在 Android 源代码树中生成 networkstack 密钥。

```

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

```makefile

device/yoyodyne/apps/SpecialApp/Android.mk

```

以下是根据提供的内容重构的代码段,并保持了段落结构:

```plaintext

LOCAL_CERTIFICATE := device/yoyodyne/security/special

device/yoyodyne/security/special.{x509.pem,pk8}

高级签名选项

APK 签名密钥替换

sign_target_files_apks

--key_mapping--default_key_mappings

--key_mapping src_key=dest_key--default_key_mappings dirbuild/target/product/security--key_mapping

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

build/target/product/security/networkstack = dir/networkstack

--extra_apks apk_name1,apk_name2,...=keykey

build/target/product/securitydevice/yoyodyne/security/special

```

请注意,我已将代码格式化为纯文本形式以便阅读。如果您需要将其转换回Markdown格式,请告诉我。

以下是重构后的内容,并保持了段落结构:

```

所有应用签名如下所示:

- vendor/yoyodyne/security/tardis/releasekey.x509.pem (release key)

- vendor/yoyodyne/security/tardis/releasekey.pk8 (PKCS#8 格式的 release key)

- vendor/yoyodyne/security/tardis/platform.x509.pem (平台证书)

- vendor/yoyodyne/security/tardis/platform.pk8 (PKCS#8 格式的平台证书)

- vendor/yoyodyne/security/tardis/shared.x509.pem (共享证书)

- vendor/yoyodyne/security/tardis/shared.pk8 (PKCS#8 格式的共享证书)

- vendor/yoyodyne/security/tardis/media.x509.pem (媒体证书)

- vendor/yoyodyne/security/tardis/media.pk8 (PKCS#8 格式的媒体证书)

- vendor/yoyodyne/security/tardis/networkstack.x509.pem (网络栈证书)

- vendor/yoyodyne/security/tardis/networkstack.pk8 (PKCS#8 格式的网络栈证书)

- vendor/yoyodyne/security/special.x509.pem (特殊应用证书)

- vendor/yoyodyne/security/special.pk8 (PKCS#8 格式的特殊应用证书)

注意:前者未加密码保护,后者已加密码保护。

```

以下是重构后的内容:

```

在当前目录下的build/make/tools/releasetools/sign_target_files_apks目录中执行以下命令:

./sign_target_files_apks

--default_key_mappings vendor/yoyodyne/security/tardis

--key_mapping vendor/yoyodyne/security/special=vendor/yoyodyne/security/special-release

--extra_apks PresignedApp=

-o tardis-target_files.zip

signed-tardis-target_files.zip

```

执行上述命令后,会将结果保存在名为tardis-target_files.zip的文件中。

以下是重构后的内容:

```

输入供应商/yoyodyne/security/special-release密钥的密码:

输入供应商/yoyodyne/security/tardis/networkstack密钥的密码:

输入供应商/yoyodyne/security/tardis/media密钥的密码:

输入供应商/yoyodyne/security/tardis/platform密钥的密码:

输入供应商/yoyodyne/security/tardis/releasekey密钥的密码:

输入供应商/yoyodyne/security/tardis/shared密钥的密码:

签名:Phone.apk (供应商/yoyodyne/security/tardis/platform)

签名:Camera.apk (供应商/yoyodyne/security/tardis/media)

签名:NetworkStack.apk (供应商/yoyodyne/security/tardis/networkstack)

签名:Special.apk (供应商/yoyodyne/security/special-release)

签名:Email.apk (供应商/yoyodyne/security/tardis/releasekey)

[...]

签名:ContactsProvider.apk (供应商/yoyodyne/security/tardis/shared)

签名:Launcher.apk (供应商/yoyodyne/security/tardis/shared) 不签名:PresignedApp.apk(由于特殊证书字符串而跳过)

重写 SYSTEM/build.prop: 替换: ro.build.description=tardis-user Eclair ERC91 15449 test-keys with: ro.build.description=tardis-user Eclair ERC91 15449 release-keys 替换: 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

签名:framework-res.apk (供应商/yoyodyne/security/tardis/platform)

重写 RECOVERY/RAMDISK/default.prop: 替换: ro.build.description=tardis-user Eclair ERC91 15449 test-keys with: ro.build.description=tardis-user Eclair ERC91 15449 release-keys 替换: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/test-keys with: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair

在 Android 10 中,引入了 APEX 文件格式,用于安装较低级别的系统模块。APEX 签名中提到,每个 APEX 文件都需要使用两个密钥进行签名:一个用于 APEX 中的迷你文件系统映像,另一个用于整个 APEX。为了实现这一目标,需要替换签名密钥。

要替换签名密钥,可以使用 `--extra_apex_payload` 和 `--extra_apks` 参数。以下是一个示例命令:

```bash

zip --output my_apex.zip ANDROID_PW_FILE EXTRA_APEX_PAYLOAD EXTRA_APKS

```

其中:

- `ANDROID_PW_FILE` 是包含签名密钥的文件;

- `EXTRA_APEX_PAYLOAD` 是包含 APEX 文件的文件;

- `EXTRA_APKS` 是包含额外 APK 文件的文件。

在这个示例中,我们将这些文件打包成一个名为 `my_apex.zip` 的 ZIP 文件。

以下是重构后的文本内容:

```csharp

{

"name": ["com.android.conscrypt.apex", "com.android.media.apex", "com.android.runtime.release.apex"],

"public_key": ["PRESIGNED", "PRESIGNED", "vendor/yoyodyne/security/testkeys/com.android.runtime.avbpubkey"],

"private_key": ["PRESIGNED", "PRESIGNED", "vendor/yoyodyne/security/testkeys/com.android.runtime.pem"],

"container_certificate": ["PRESIGNED", "PRESIGNED", "vendor/yoyodyne/security/testkeys/com.google.android.runtime.release_container.x509.pem"],

"container_private_key": ["PRESIGNED", "PRESIGNED", "vendor/yoyodyne/security/testkeys/com.google.android.runtime.release_container.pk8"]

}

您拥有以下包含发布密钥的文件:

- vendor/yoyodyne/security/runtime_apex_container.x509.pem

- vendor/yoyodyne/security/runtime_apex_container.pk8

- vendor/yoyodyne/security/runtime_apex_payload.pem

```

```

2019-10-25 14:36:47,788 INFO: [com.android.runtime.release.apex] com.yoyodyne.security.SignApkTask#execute(List) called

2019-10-25 14:36:47,788 INFO: [com.android.runtime.release.apex] Task is executing for target apex_container

2019-10-25 14:36:47,788 INFO: [com.android.runtime.release.apex] Setting up key mappings and payload keys

2019-10-25 14:36:47,788 INFO: [com.android.runtime.release.apex] Key mappings are set to: runtime=tardis_payload=runtime_apex_container

2019-10-25 14:36:47,788 INFO: [com.android.runtime.release.apex] Payload keys are set to: runtime_apex_container=tardis_payload=runtime_apex_payload.pem

2019-10-25 14:36:47,788 INFO: [com.android.runtime.release.apex] Additional APKs are set to: com.android.runtime.release.apex=vendor/yoyodyne/security/runtime_apex_container

2019-10-25 14:36:47,788 INFO: [com.android.runtime.release.apex] Additional APKPEMs are set to: com.android.runtime.release.apex=vendor/yoyodyne/security/runtime_apex_payload

2019-10-25 14:36:47,788 INFO: [com.android.runtime.release.apex] Additional APKs are set to: com.android.media.apex=

2019-10-25 14:36:47,788 INFO: [com.android.runtime.release.apex] Additional APKPEMs are set to: com.android.media.apex=

2019-10-25 14:36:47,788 INFO: [com.android.runtime.release.apex] Creating tardis-target_files.zip

2019-10-25 14:36:47,788 INFO: [com.android.runtime.release.apex] Signing target files with the specified key mappings and payload keys

2019-10-25 14:36:47,788 INFO: [com.android.runtime.release.apex] Tardis target files have been signed and zipped as tardis-target_files.zip in the current working directory

```

以下是根据提供的内容重构后的代码示例:

```python

# 生成RSA密钥对

openssl genrsa -3 -out temp.pem 2048

# 使用公钥部分生成证书

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'

```

上述代码使用`openssl`工具生成了一个RSA密钥对。首先,使用`genrsa`命令生成一个具有2048位长度的RSA私钥,并将输出存储在名为`temp.pem`的文件中。然后,使用`req`命令结合私钥部分和指定的证书信息生成一个自签名的X.509证书,并将输出保存为名为`releasekey.x509.pem`的文件。最后,证书的有效期设置为10,000天。

以下是重构后的内容:

首先,我们需要创建一个PKCS#8格式的私钥版本。在终端中执行以下命令:

```bash

openssl pkcs8 -in temp.pem -topk8 -outform DER -out releasekey.pk8 -nocrypt

```

接下来,我们需要安全地删除临时文件temp.pem。在终端中执行以下命令:

```bash

shred --remove temp.pem

```

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

然后,我们需要创建一个包含签名目标文件的zip文件。在终端中执行以下命令:

```bash

img_from_target_files signed-target_files.zip signed-img.zip

```

生成的文件包括:

- signed-img.zip

- 包含所有.img文件。

要将映像加载到设备上,请使用fastboot,如下所示:

```bash

fastboot update signed-img.zip

```