本頁面說明如何驗證 Android 裝置上安裝的 APK 或 APEX 是否與聲明者模型中的聲明相符。這個程序包括從裝置擷取 APK,並對擷取的構件執行記錄納入證明。
驗證程序
透明化記錄是透過由雜湊組成的默克爾樹實作。 葉節點包含資料,父項節點則包含子項的雜湊值。
兩項基本運算會驗證透明度記錄的防竄改特性:納入證明和一致性證明。內含證明會確認記錄檔是否包含特定 APK 版本的項目。這個記錄項目包含雜湊,也就是安裝在裝置上的 APK 檔案的 SHA256 摘要。 一致性證明可確保新增項目時,新的檢查點在密碼編譯方面與樹狀結構的先前版本保持一致 (或樹狀結構未遭竄改)。本指南著重於計算納入證明程序的過程,同時依賴見證人持續對最新檢查點執行一致性證明。
如要驗證涵蓋的 APK,請針對見證的檢查點執行納入證明。請注意,我們計畫使用標準化見證通訊協定,將這項記錄與公開見證網路整合。這項整合功能會提供見證檢查點,確保記錄檔的一致性。
如要確認裝置上的 Google 應用程式是否符合申請人模型中的聲明,請按照下列步驟操作。
收錄證明
如要確認裝置上受保護的 APK 是否在記錄中,請擷取 APK、計算其雜湊值,然後使用納入證明檢查該雜湊值是否存在於已發布的檢查點。如果包含證明成功,就能防範威脅模型中所述的風險,並確認應用程式是正當的 Google 應用程式。
如何驗證記錄檔中是否包含 APK
任何聲稱是 Google 第一方應用程式的應用程式,都可以根據這個記錄進行驗證。
驗證的必要條件
驗證擷取的 APK 前,請先在電腦上安裝下列工具:
Android Debug Bridge (ADB)
ADB 是與 Android 裝置通訊的工具,可從 Android SDK 平台工具網站取得。
AAPT2
AAPT2 (Android 資產封裝工具) 是一種建構工具,用於編譯及封裝 Android 應用程式的資源。在 Android SDK Build Tools 26.0.2 以上版本中,AAPT2 是獨立工具。
Golang
驗證工具是以 Go 語言編寫。如要建構該工具,請從 Go 網站安裝 Go 1.17 以上版本。
Inclusion Proof 驗證器
我們會在 android-binary-transparency GitHub 存放區中發布名為 verifier 的 Go 模組。這項工具會查詢 Google 第一方 APK 透明化記錄,檢查是否包含套件。
如要使用這項工具,請先將存放區複製到本機電腦:
git clone https://github.com/android/android-binary-transparency
您可以在 android-binary-transparency 存放區中找到驗證器的原始碼。
建構驗證酬載
如要驗證擷取的 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 的檔案。
這個檔案會列出每個已安裝的套件,以及設為 true 或 false 的 inclusion_proof_verified 欄位。true 值表示系統已根據透明化記錄,以密碼編譯方式驗證套件,確認套件符合記錄的聲明。