使用avbtool 为Android 镜像签名以启动主线Linux

本文最后更新于:3 分钟前

使用avbtool 为Android 镜像签名以启动主线Linux

本文使用了AI进行润色,因为这篇文章前后打磨花费了超出预期的时间,所以格式上将不再进行调整。请自行使用 Markdown 渲染器查看。

本文记录了我使用 avbtool 为 Android 镜像签名、从而在设备上启动主线 Linux 的过程。
本人对 AVB 和 Android 了解有限,计算机相关知识大多自学而来,本文仅供参考,可能存在错误或不严谨之处,请勿较真
文中所有命令仅在 Linux 环境下测试,其他平台不保证适用。


AVB 简介

AVB(Android Verified Boot) 是 Android 用于验证启动分区合法性的一套标准,用来建立从 bootloader 到系统镜像的信任链,并提供回滚保护等安全功能。

启用 AVB 需要一对密钥:

  • 公钥(信任根) 的哈希值由厂商烧录到 SoC;
  • 私钥 用于对系统镜像签名。

在启动过程中,ABL(Android Bootloader) 会验证签名与哈希值。
系统中还存在一个关键分区——vbmeta,其中记录了多个分区的签名及哈希信息。vbmeta 还可以指向若干“链式验证分区”,其结构与 vbmeta 相似,只是不会再嵌套指向其他分区。主要字段包括:

  • 公钥(哈希值)
  • 回滚指数
  • 分区名及对应哈希算法
  • 数据摘要(固定长度哈希字符串)等。

查看 vbmeta 信息

使用以下命令可查看 vbmeta 中的相关信息:

avbtool info_image –image vbmeta.img

注**:avbtool 是一个 Python 脚本,可直接从网络获取。
Windows 环境下可能需要改为 python avbtool 并确保依赖模块已安装。


非链式验证分区,可使用如下命令添加 Hash Footer(但不是必需的,因为 ABL 只会核对这些分区对应在 vbmeta 中的信息):

1
2
3
4
5
6
7
avbtool add_hash_footer \
--image <path_to_image> \
--partition_size <partition_size> \
--partition_name <partition_name> \
--algorithm <algorithm> \
--salt <salt_string> \
--key <path_to_private_key>

在学习和使用上述命令时, 为了避免对 openssl 命令的介绍,
示例中私钥直接用 AOSP 提供的 测试密钥(RSA4096),对应算法为 SHA256_RSA4096
这是公开的测试私钥,仅供学习,请绝不能用于生产环境

⚠️ 警告:即便如此,仍有厂商在零售设备中使用了测试或公开密钥。(如某个电视大厂和通信大厂,这里就不点名了)

常见公开测试密钥汇总可参考:
test_avb_key

提取公钥并查看其哈希:

1
2
3
4
for pem in *.pem; do
avbtool extract_public_key --key "$pem" --output "${pem%.*}.bin"
sha1sum "${pem%.*}.bin"
done

其中包含

60daed9eaef7456fd487433866a56d597f25b326 testkey_rsa4096_oneplus.bin

不幸的是我们可以在新的一加设备上发现, 对应的公钥哈希是

1
2
3
avbtool info_image --image vbmeta.img | grep 'Public key'

Public key (sha1): 521801a1ce15f70ee1cb3c1cbf2102da46fe5d5a

链式验证分区(以 boot 为例)

链式验证分区(如 boot必须包含 Hash Footer,因为 vbmeta 中只记录其公钥信息,不保存具体哈希。
若缺失,将触发 avb_slot_verify.c 中的错误(load_and_verify_vbmeta()):

1
ERROR: boot_a: Error verifying vbmeta image: invalid vbmeta header

此外,还可能遇到:

1
2
Footer osP_version prop not found
Boot image header OS version == 0

原因是 VerifiedBoot.c 中的 GetOsVerAndSecPactchLevel() 未能找到 Android 版本信息。
解决方案:在 avbtool 命令中加入以下属性:

1
2
--prop com.android.build.boot.os_version:'15'
--prop com.android.build.boot.security_patch:'2025-02-05'

或在构建 boot 镜像时直接设置:

1
2
3
4
5
6
7
mkbootimg \
--kernel vmlinuz \
--ramdisk initramfs \
...
--os_version 15 \
--os_patch_level 2025-02-05 \
-o mainline-boot.img

回滚保护

若添加 Hash Footer 时未指定回滚指数,默认值为 0。
若该值小于 **RPMB 中的已存回滚指数,启动时将报错:

ERROR: boot_a: Image rollback index is less than the stored rollback index.

解决方法:在签名时指定一个不小于原厂系统值的回滚指数,例如:

–rollback_index


启动主线 Linux

至此,boot 分区已正确签名,可以在解锁状态下顺利启动主线 Linux。
特别是厂商定制的 ABL 禁止关闭 AVB(但允许部分分区 Hash Mismatch),这种方式尤其必要。


写到这里,本文已经远超原计划的篇幅。剩余细节留待读者自行探索。

参考文献:点击查看



使用avbtool 为Android 镜像签名以启动主线Linux
https://moranwp.eu.org/avbtool.html
作者
墨染_nlx
发布于
2025年9月21日
许可协议