Google 產品應用程式資訊公開完整驗證

本頁說明如何驗證 Android 裝置上安裝的 APK 或 APEX 是否與聲明人模型中的聲明相符。這個程序包括從裝置擷取 APK,並對擷取的構件執行記錄納入證明。

驗證程序

透明度記錄是透過由雜湊組成的 Merkle 樹實作。 葉節點包含資料,父項節點則包含子項的雜湊值。

兩項基本運算會驗證透明度記錄的防竄改特性:納入證明和一致性證明。納入證明會確認記錄檔是否包含特定 APK 版本的項目。這個記錄項目包含雜湊,也就是安裝在裝置上的 APK 檔案的 SHA256 摘要。 一致性證明可確保新增項目時,新的檢查點在密碼學上與樹狀結構的先前版本保持一致 (或樹狀結構未遭竄改)。本指南著重於計算納入證明程序的過程,同時依賴見證人持續對最新檢查點執行一致性證明。

如要驗證涵蓋的 APK,請針對見證的檢查點執行納入證明。請注意,我們計畫使用標準化見證協定,將這項記錄與公開見證網路整合。這項整合功能會提供見證檢查點,確保記錄檔的一致性。

如要確認裝置上的 Google 應用程式符合申請人型號中的聲明,請按照下列步驟操作。

收錄證明

如要確認裝置上受保護的 APK 是否在記錄中,請擷取 APK、計算其雜湊值,然後使用納入證明檢查該雜湊值是否存在於已發布的檢查點。如果成功提供納入證明,即可防範威脅模型中所述的風險,並確認應用程式是正當的 Google 應用程式。

如何驗證 APK 是否已納入記錄

任何聲稱是 Google 第一方應用程式的應用程式,都可以根據這個記錄進行驗證。

通過認證的必要條件

在驗證構件 (韌體或 APK) 是否符合聲明之前,請先確認連網電腦上是否備妥下列工具:視驗證目標而定,您可能不必提供所有資訊。

Golang

驗證工具是以 Go 語言編寫。如要建構該工具,請從 Go 網站安裝 Go 1.24 以上版本。

Android Debug Bridge (ADB)

ADB 工具可與 Android 裝置通訊,檢查映像檔或擷取 APK,可從 Android SDK 平台工具網站取得。

Inclusion Proof 驗證器

納入證明驗證器是 Go 模組,可查詢透明度記錄,並輸出構件是否納入記錄。這項資訊發布在 android-binary-transparency GitHub 存放區,網址為: https://github.com/android/android-binary-transparency/tree/main

如要複製 AOSP avb 存放區,請執行下列指令:

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

如要複製 android-binary-transparency GitHub 存放區,請按照下列步驟操作:

computer:~$ git clone https://github.com/android/android-binary-transparency

AAPT2

AAPT2 (Android 資產封裝工具) 是一種建構工具,用於編譯及封裝 Android 應用程式的資源。在 Android SDK Build Tools 26.0.2 以上版本中,AAPT2 是獨立工具。

bundletool

bundletool 是用於建構 Android App Bundle (AAB) 的工具。這個工具也可用於驗證 APK 程式碼簽章。可從 GitHub 下載。

wget 或 curl

wgetcurl 是可用來從網際網路擷取或下載檔案的工具。請務必安裝其中一項工具,因為驗證指令碼可能會用到。

Avbtool

avbtool 用於計算工廠映像檔的 VBMeta 摘要,以及驗證二進位檔。複製 avb 存放區後 (如「納入證明驗證器」一節所示),您可以在複製的 avb 目錄中找到 avbtool.py。您應將這個目錄新增至 $PATH 環境變數。

computer:~$ PATH=$PATH:DIRECTORY_CONTAINING_AVBTOOL

Fbpacktool

fbpacktool 是用來解壓縮 Pixel bootloader.img 中個別元件的 Python 指令碼。如果您要驗證 APK,則不需要這個檔案。 這項工具非常重要,因為可讓 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

建構驗證酬載

如要驗證擷取的 APK,您必須使用從 APK 本身衍生的資訊建構記錄檔酬載。

開始前,請先在裝置上啟用 USB 偵錯,允許 adb 連線。

接著,在裝置上找出已安裝的 APK。本指南以 Google Play 服務 APK (com.google.android.gms) 做為工作範例。

adb shell pm path com.google.android.gms

輸出結果應該會類似下列內容:

computer:~$ adb shell pm path com.google.android.gms
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/base.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_CronetDynamite_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_DynamiteLoader_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_DynamiteModulesA_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_DynamiteModulesC_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_GoogleCertificates_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_MapsDynamite_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_MeasurementDynamite_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_config.en.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_config.xxhdpi.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_maps_core_dynamite_ondemand.apk

這項輸出內容表示裝置上已安裝 com.google.android.gms 的一個基準 APK 和數個分割 APK。確切的分割 APK 數量會因裝置設定而異。 每個分割 APK 都與基本 APK 共用相同的套件名稱和版本代碼。

使用下列指令,將列出的 APK 從 Android 裝置下載到電腦 (請注意,實際檔案路徑可能有所不同):

mkdir -p /tmp/testdir/gms && cd /tmp/testdir/gms && \
adb shell pm path com.google.android.gms | cut -d':' -f2 | tr -d '\r' | xargs -n1 adb pull

如要驗證下載的 APK 套件名稱和版本,請檢查其資訊清單 (AndroidManifest.xml)。

由於 APK 內的資訊清單採用二進位格式,請使用 aapt2 工具 (在必要條件步驟中安裝),直接從 APK 擷取並讀取資訊:

computer:/tmp/testdir/gms$ aapt2 dump badging ./base.apk
package: name='com.google.android.gms' versionCode='260834035' versionName='26.08.34 (260400-876566425)' platformBuildVersionName='Baklava' platformBuildVersionCode='36' compileSdkVersion='36' compileSdkVersionCodename='Baklava'
minSdkVersion:'35'
targetSdkVersion:'36'
...

您應重複這個步驟,直到取得所有安裝在裝置上的分割 APK 相關資訊為止。

輸出內容會確認 APK 的套件名稱為 com.google.android.gms,且版本號碼 (versionCode) 為 260834035

接著,計算每個 APK 的加密雜湊:

computer:/tmp/testdir/gms$ sha256sum *.apk
66aa2d7b9752cdd61065b55c8e16739d8367fa18a0f1c8c84122369f86958f1a  base.apk
c20754aee886cc55a9de91ee15c623c59d94ad22b7e435a1a48afc43cf1a106c  split_config.en.apk
68c09b63a1262e0d34020c139bc77deff3c32bd2b01177abac64790a62fb3be6  split_config.xxhdpi.apk
cd746820c27babd855fa5daea6fabcdf7b44abf3060bc547adc4219212410af0  split_CronetDynamite_installtime.apk
512ee48b60fdb0787a17f84a7dc448fdbf885b2b86a9cb50525d4c22d561b0f1  split_DynamiteLoader_installtime.apk
9e0c74bdc75c50c80d4e2e580a7eda6b8391423ab1161645f41ec6cadc07d678  split_DynamiteModulesA_installtime.apk
955780ac01f59b98bd9be12968f3824ad71b762620f7bf223c569c1a6ab7056c  split_DynamiteModulesC_installtime.apk
34c4a2e32d31554d55fc1519e2cfc3ed5027a090fb29b54cfc99f42d1da43bc5  split_GoogleCertificates_installtime.apk
475e18dde92472cde9d8300c082b6dc269613db03398bcd9d1987dff3e68f7b5  split_maps_core_dynamite_ondemand.apk
f83faf40f08bc13f4879302e01c08c863ca2304b4b4e7c9eaf8cd1e869bb6573  split_MapsDynamite_installtime.apk
ec6d854ddda6cd1ba2ba7af2d9fdf4f28c5c78be8713c64521c785429296738c  split_MeasurementDynamite_installtime.apk

您現在已取得所有必要資訊,可以建構記錄酬載,並按照記錄內容一節所述格式設定。從結果中選取一個雜湊做為範例 (您應驗證每個分割 APK 的雜湊),記錄檔有效負載如下所示:

66aa2d7b9752cdd61065b55c8e16739d8367fa18a0f1c8c84122369f86958f1a
SHA256(APK)
com.google.android.gms
260834035

請務必在檔案結尾加入換行字元。將這項內容儲存到檔案 (例如 payload.txt),以便稍後搭配 verifier 工具使用。

驗證套件是否包含在內 (包含證明)

建構酬載後,您現在可以檢查套件是否包含在透明度記錄中。從您先前複製的 android-binary-transparency 存放區建構納入證明工具:

go build cmd/verifier/verifier.go

該目錄中應該會產生名為 verifier 的可執行檔。 執行驗證工具,提供酬載路徑並指定記錄類型:

computer:android-binary-transparency$ PAYLOAD_PATH=PATH_TO_PAYLOAD_DIR/payload.txt
computer:android-binary-transparency$ ./verifier --payload_path=${PAYLOAD_PATH} --log_type=google_1p_apk

驗證者會使用檢查點和記錄內容 (來自圖塊目錄),檢查 APK 酬載是否位於透明度記錄中,確認是由 Google 發布。

指令會輸出至 stderr

  • 如果套件包含在記錄中。OK. inclusion check success!
  • FAILURE (如果不是)。

自動驗證裝置中的所有封裝

裝置上可能預先安裝了許多 Google 應用程式,逐一列舉並個別執行納入證明可能很麻煩。

我們提供另一項名為 Uraniborg 的自動化工具,可偵測及測量裝置上目前安裝的所有套件。這項工具會直接將輸出內容提供給 verifier 工具,讓您只需一個步驟,就能探索及驗證裝置上所有應用程式的透明度。

如要使用這項自動化工作流程,請確認 Android 裝置已透過 ADB 連接至電腦。Uraniborg存放區也包含 Uraniborg原始碼。android-binary-transparency

執行 scripts/python 目錄中的 automate_observation.py 指令碼:

python3 automate_observation.py --pull-all-apks --perform_inclusion_proof_check --verifier_path <path_to_verifier_executable>

指令碼執行完畢後,您應該會看到類似以下的輸出內容:

INFO:automate_observation.py:main(858): SUCCESS! Hubble was successfully deployed and executed on connected device ABCDEFGHN01234.
INFO:automate_observation.py:main(860): Hubble output files can be found at: /Users/user/home/src/android-binary-transparency/uraniborg/scripts/python/results/google/lynx/lynx:16/BP4A.260105.004.E1/14587043:user/release-keys/001

前往指令碼所指的輸出目錄。在該資料夾中,找出名為 packages_with_inclusion_proof_signal.txt 的檔案。 這個檔案會列出每個已安裝的套件,以及設為 truefalseinclusion_proof_verified 欄位。true 值表示系統已根據透明化記錄,以密碼編譯方式驗證套件,確認套件符合記錄的聲明。