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 平台工具網站取得。

納入證明驗證工具

納入證明驗證工具是 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 以上版本中,您可以找到這個獨立工具。

bundletool

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

wget 或 curl

wget 和 curl 是可用於從網際網路擷取或下載檔案的工具。請務必安裝其中一項工具,因為驗證指令碼可能會依賴這些工具。

Avbtool

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

computer:~$ PATH=$PATH:DIRECTORY_CONTAINING_AVBTOOL

Fbpacktool

fbpacktool 是一種 Python 指令碼,用於解壓縮 Pixel 的 bootloader.img 中的個別元件。如果您要驗證 APK,則不需要這個檔案。 這項工具很重要,因為 avbtool.py 可透過這項工具找到驗證所需的圖片。

fbpacktool 需要 Python 3.6 以上版本和 PyYAML 套件 (例如 python3 -m pip install pyyaml)。

如要使用這項工具,請將下列六個 Python 指令碼下載到 avbtool.py 所在的目錄,將 fbpacktool.py 設為可執行,並建立名為 fbpacktool 的符號連結,指向 fbpacktool.py,以便使用。

如果你有 wget:

computer:dir_to_avbtool$ wget https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/fbpacktool.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/fbpack.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/packedstruct.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/xmlparser.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/xmlserializer.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/yamlparser.py
computer:dir_to_avbtool$ chmod +x fbpacktool.py
computer:dir_to_avbtool$ ln -s fbpacktool.py fbpacktool

如果你有 curl:

computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/fbpacktool.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/fbpack.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/packedstruct.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/xmlparser.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/xmlserializer.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/yamlparser.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 共用相同的套件名稱和版本代碼。

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

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 原始碼也包含在 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 的檔案。這個檔案會列出每個已安裝的套件,以及設為 true 或 false 的 inclusion_proof_verified 欄位。true 值表示系統已根據資訊公開記錄,以密碼編譯方式驗證套件,確認套件符合記錄的聲明。