驗證方式

本頁將說明一種方法 (可提供最高程度的信心),確保您可以在 Pixel 裝置上執行 Pixel 圖像的正版。這項作業包括將原始映像檔下載到電腦上,然後對下載的構件執行記錄納入證明,再將其更新到裝置上。

如何驗證 Pixel 原始映像檔

驗證前必要條件

在繼續驗證您剛下載的工廠映像檔是否符合我們的聲明之前,請透過已連上網路的電腦執行下列操作。

Go 語言

驗證工具是使用 Go 編寫。如要建構此工具,請從 Go 網站安裝 Go 1.17 以上版本。

wget 或 curl

wgetcurl 是可用來從網路擷取或下載檔案的工具。請務必在系統上安裝這兩種工具,因為本指南的其餘部分和我們提供的指令碼都需要其中一個工具。

Avbtool

avbtool 可用來計算工廠映像檔的 VBMeta 摘要,以及驗證二進位檔。

您可以使用下列指令從 Android 開放原始碼計畫存放區下載,並在連結的說明文件中查看更多詳細資訊。

computer:~$ git clone https://android.googlesource.com/platform/external/avb

複製該存放區後,您可以在複製的 avb 存放區目錄中找到 avbtool.py。此外,您也應將這個目錄新增至 $PATH 環境變數。

computer:~$ PATH=$PATH:DIRECTORY_CONTAINING_AVBTOOL

包容證明驗證器

包含證明驗證器是 Go 模組,可查詢 Pixel 工廠圖片透明度記錄,並輸出圖片是否包含在記錄中。

複製上述 AVB 存放區後,您會在 tools/transparency/verify/ 中找到驗證器的原始碼

Fbpacktool

fbpacktool 是 Python 指令碼,用於解開 Pixel bootloader.img 中的個別元件。這項工具對於讓 avbtool.py 找出驗證所需的圖片至關重要。

如要使用這項工具,請將下列三個 Python 指令碼下載至 avbtool.py 所在的目錄,讓 fbpacktool.py 可供執行,並建立名為 fbpacktool 的符號連結至 fbpacktool.py,以利操作。

如果您有 wget,可以發出以下指令來下載這三個指令碼:

computer:dir_to_avbtool$ wget https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/fbpacktool.py \
https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/fbpack.py \
https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/packedstruct.py
computer:dir_to_avbtool$ chmod +x fbpacktool.py
computer:dir_to_avbtool$ ln -s fbpacktool.py fbpacktool

如果您有 curl,可以發出以下指令來下載這三個指令碼:

computer:dir_to_avbtool$ curl -O https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/fbpacktool.py
computer:dir_to_avbtool$ curl -O https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/fbpack.py
computer:dir_to_avbtool$ curl -O https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/packedstruct.py
computer:dir_to_avbtool$ chmod +x fbpacktool.py
computer:dir_to_avbtool$ ln -s fbpacktool.py fbpacktool

OpenSSL

您還需要名為 openssl 的工具,以便在驗證工作流程中使用終端機執行各種加密編譯作業。請確認已在系統上安裝該套件。您可以透過發出以下指令,在終端機上進行檢查,並確保傳回的結果不為空白。例如:

computer:~$ which openssl
/usr/bin/openssl

建構驗證酬載

如要驗證裝置上的映像檔或從 Pixel 工廠圖片網站下載的映像檔,您必須先從建構指紋和 VBMeta 摘要中,建構與該映像檔相對應的酬載。您可以選擇手動或自動,如下所述。

  • 版本指紋:工廠映像檔的字串 ID
    • 例如: google/oriole/oriole:12/SD1A.210817.015.A4/7697517:user/release-keys
  • VBMeta 摘要:SHA-256 加密編譯摘要,可將工廠映像檔的不同部分連結在一起
    • 例如: 4d5e41b7c675a821de81f7d2c744623fe808c8c2d3e19a83e894dab5d0829dbe

手動酬載建構

如要手動產生驗證酬載,您需要建立文字檔案 payload.txt,其中包含建構指紋 (位於一行) 和 VBMeta 摘要 (位於下一行),並加上空白新行 (請參閱「記錄內容」一節,瞭解確切格式)。

按照工廠原始映像檔網站中的步驟操作後,payload.txt 檔案的內容應如下所示:

google/oriole/oriole:12/SD1A.210817.015.A4/7697517:user/release-keys
4d5e41b7c675a821de81f7d2c744623fe808c8c2d3e19a83e894dab5d0829dbe
從 Pixel 工廠映像檔網站中擷取 VBMeta 摘要和版本指紋

Pixel 原廠映像檔網站下載原廠映像檔時,您必須解壓縮下載的檔案,系統會在原處建立另一個資料夾。前往新建立的資料夾,並解壓縮相關聯的 image-*.zip 檔案,取得個別的 *.img 檔案。這些二進位檔是分割區映像檔。請確認 img 檔案中含有 vbmeta.img 檔案。畫面應如下所示:

computer:oriole-sd1a.210817.015.a4$ unzip image-oriole-sd1a.210817.015.a4.zip
Archive:  image-oriole-sd1a.210817.015.a4.zip
  inflating: android-info.txt
  inflating: boot.img
  inflating: vendor_boot.img
  inflating: system.img
  inflating: vendor.img
  inflating: product.img
  inflating: system_ext.img
  inflating: system_other.img
  inflating: dtbo.img
  inflating: vbmeta_system.img
  inflating: vbmeta.img
  inflating: super_empty.img

您可以從所有下載的檔案中擷取建構指紋,並計算 VBMeta 摘要。

avbtool.py 提供給 $PATH 後,您就可以透過終端機發出下列指令,擷取版本指紋,並計算您剛下載的出廠映像檔 VBMeta 摘要:

computer:dir_containing_unzipped_factory_image~$ grep -a 'ro\..*build\.fingerprint=google/.*/release-keys' system.img | cut -f2 -d'='
google/oriole/oriole:12/SD1A.210817.015.A4/7697517:user/release-keys
computer:dir_containing_unzipped_factory_image$ avbtool.py calculate_vbmeta_digest --image vbmeta.img
4d5e41b7c675a821de81f7d2c744623fe808c8c2d3e19a83e894dab5d0829dbe
手動驗證已下載的原廠映像檔

為了正確驗證下載的工廠映像檔,您需要下載 fbpacktool.py 和其他兩個依附於此的 Python 檔案 (fbpack.pypackedstruct.py),以便解壓縮 bootloader.img 中的元件,因為這些元件在 VBMeta 結構體中分別有說明。取得解包工具後,您可以使用 fbpacktool.py 解包引導程式映像檔。例如:

computer:dir_containing_unzipped_images$ python3 fbpacktool.py unpack bootloader-oriole-slider-1.0-7683913.img

您應該會在該目錄中看到其他 .img 檔案。您現在可以繼續使用 avbtool.py 手動驗證各個分區的簽章是否相符。

computer:dir_containing_unzipped_images$ avbtool.py verify_image --image vbmeta.img --follow_chain_partitions
Verifying image vbmeta.img using embedded public key
vbmeta: Successfully verified SHA256_RSA4096 vbmeta struct in vbmeta.img
vbmeta_system: Chained but ROLLBACK_SLOT (which is 1) and KEY (which has sha1 df529646b7225015196a714006346f0768b87fcf) not specified
--
Verifying image vbmeta_system.img using embedded public key
vbmeta: Successfully verified SHA256_RSA4096 vbmeta struct in vbmeta_system.img
product: Successfully verified sha256 hashtree of product.img for image of 2700468224 bytes
system: Successfully verified sha256 hashtree of system.img for image of 878493696 bytes
system_ext: Successfully verified sha256 hashtree of system_ext.img for image of 251334656 bytes
vbmeta_vendor: Chained but ROLLBACK_SLOT (which is 3) and KEY (which has sha1 85322346680a860c091fa14a64cef1fe4a3ffe31) not specified
--
Verifying image vbmeta_vendor.img using embedded public key
vbmeta: Successfully verified SHA256_RSA4096 vbmeta struct in vbmeta_vendor.img
vendor: Successfully verified sha256 hashtree of vendor.img for image of 472940544 bytes
boot: Chained but ROLLBACK_SLOT (which is 2) and KEY (which has sha1 85322346680a860c091fa14a64cef1fe4a3ffe31) not specified
--
Verifying image boot.img using embedded public key
vbmeta: Successfully verified footer and SHA256_RSA4096 vbmeta struct in boot.img
boot: Successfully verified sha256 hash of boot.img for image of 24481792 bytes
abl: Successfully verified sha256 hash of abl.img for image of 1744896 bytes
bl1: Successfully verified sha256 hash of bl1.img for image of 12288 bytes
bl2: Successfully verified sha256 hash of bl2.img for image of 544768 bytes
bl31: Successfully verified sha256 hash of bl31.img for image of 86016 bytes
dtbo: Successfully verified sha256 hash of dtbo.img for image of 2152234 bytes
gsa: Successfully verified sha256 hash of gsa.img for image of 262144 bytes
ldfw: Successfully verified sha256 hash of ldfw.img for image of 4096000 bytes
pbl: Successfully verified sha256 hash of pbl.img for image of 49152 bytes
tzsw: Successfully verified sha256 hash of tzsw.img for image of 4304896 bytes
vendor_boot: Successfully verified sha256 hash of vendor_boot.img for image of 25718784 bytes
vendor_dlkm: Successfully verified sha256 hashtree of vendor_dlkm.img for image of 54505472 bytes

如果您沒有看到任何錯誤或失敗訊息,表示已成功驗證下載圖片的 VBMeta。

自動酬載建構

為方便您操作,我們也提供 Python 指令碼供您使用。使用這項工具時,您只需指定原始映像檔的網址,而無須手動擷取及解壓縮檔案。

computer:dir_to_avb_repo/tools/transparency$ python3 ./pixel_factory_image_verify.py https://dl.google.com/dl/android/aosp/oriole-sd1a.210817.015.a4-factory-074b7f51.zip
Fetching file from: https://dl.google.com/dl/android/aosp/oriole-sd1a.210817.015.a4-factory-074b7f51.zip
Successfully downloaded file.
Successfully unpacked factory image.
Successfully unpacked factory image partitions.
Successfully unpacked bootloader image.
Successfully verified VBmeta.
Successfully extracted build fingerprint.
Successfully calculated VBMeta Digest.
The build fingerprint for factory image is: google/oriole/oriole:12/SD1A.210817.015.A4/7697517:user/release-keys
The VBMeta Digest for factory image is: 4d5e41b7c675a821de81f7d2c744623fe808c8c2d3e19a83e894dab5d0829dbe

A corresponding "payload.txt" file has been created.

執行上述指令後,系統會下載工廠映像檔套件、解壓縮套件,並驗證已簽署分區的簽章。驗證成功後,系統會建立名為 payload.txt 的新檔案,內容應類似以下:

google/oriole/oriole:12/SD1A.210817.015.A4/7697517:user/release-keys
4d5e41b7c675a821de81f7d2c744623fe808c8c2d3e19a83e894dab5d0829dbe

成功建立 payload.txt 後,您可以開始驗證圖片包含狀況的步驟。

驗證圖片包含情形 (證明包含圖片)

建構完酬載後,請設定 shell 變數 (例如 $PAYLOAD_PATH),以便指向酬載路徑。

我們已在 Android 開放原始碼計畫的 avb 存放區中發布包含證明工具。如要執行這項作業,請按照下列步驟操作:

computer:external/avb/tools/transparency/verify$ PAYLOAD_PATH=../payload.txt
computer:external/avb/tools/transparency/verify$ go build cmd/verifier/verifier.go
computer:external/avb/tools/transparency/verify$ ./verifier --payload_path=${PAYLOAD_PATH} --log_type=pixel

驗證器會使用檢查點和記錄內容 (位於圖塊目錄中),檢查圖片酬載是否位於透明度記錄中,也就是由 Google 發布。

指令的輸出內容會寫入 stdout:

  • OK. inclusion check success! 如果記錄檔包含圖片,
  • FAILURE