本頁說明各種方法,確保安裝在 Android 裝置上的 APK 符合申請人模型中的聲明。這包括從裝置中提取有問題的 APK、檢查程式碼完整性,以及對擷取的構件執行記錄納入證明。
驗證程序
透明度記錄是透過由雜湊組成的 Merkle 樹實作。 葉節點包含資料,父項節點則包含子項的雜湊值。
基本上,系統會在 Merkle 樹狀結構上執行兩項運算,以驗證透明度記錄的防竄改特性:納入證明和一致性證明。前者可證明記錄包含與特定 APK 版本相應的項目。記錄檔項目包含雜湊,也就是程式碼簽章權杖的 SHA256 摘要,格式為 JSON Web Token (JWT),可從對應的 APK 取得。後者證明在樹狀結構中新增項目時,新的檢查點會與樹狀結構的先前版本 (以密碼編譯方式) 保持一致。
如要驗證涵蓋範圍內的 APK,請根據見證的檢查點執行納入證明測試。請注意,我們計畫使用標準化的見證協定,將這項記錄與公開見證網路整合。這會提供經過見證的檢查點,確保記錄的一致性。
如要確認裝置上的 APK 是否符合聲明人模型中的聲明,請參閱下文。
收錄證明
Android 使用者可以先擷取裝置上受保護的 APK 及其相關中繼資料,然後比較重新計算的根雜湊值與已發布檢查點中包含的根雜湊值,確認 APK 是否在記錄中。如果相符,Android 使用者就能獲得威脅模型中所述的保護措施。
如何驗證 APK 是否已納入記錄
如前所述,目前涵蓋的 APK 清單會列在總覽頁面中。
通過認證的必要條件
在驗證構件 (韌體或 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
wget 和 curl 是可用來從網際網路擷取或下載檔案的工具。請務必安裝其中一項工具,因為驗證指令碼可能會用到。
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 衍生資訊建構記錄檔酬載。
開始之前,請先在裝置上啟用 ADB 偵錯,確認裝置可以使用 adb。
然後找出裝置上安裝 APK 的位置。在本指南中,我們將使用 Android System Key Verifier APK (com.google.android.contactkeys) 做為工作範例。
computer:~$ adb shell pm list packages -f | grep contactkeys
package:/data/app/~~i5WYSO4PuAAv798-eHdM7A==/com.google.android.contactkeys-PQCKjnn7xDqjeVhcUDibBA==/base.apk=com.google.android.contactkeys
如果裝置上已安裝 Android System Key Verifier APK,上述指令會傳回路徑,指出該 APK 在裝置上的安裝位置。否則不會看到任何輸出內容。
接著,使用下列指令,將 Android 裝置上的 APK 下載到您使用的電腦 (請注意,裝置上的實際位置和 APK 檔案名稱可能有所不同):
computer:~$ mkdir -p /tmp/testdir && cd /tmp/testdir
computer:/tmp/testdir$ adb pull /data/app/~~i5WYSO4PuAAv798-eHdM7A==/com.google.android.contactkeys-PQCKjnn7xDqjeVhcUDibBA==/base.apk ./contactkeys_candidate.apk
如要取得並驗證剛下載的 APK 套件名稱,請先解壓縮 APK,因為 APK 最終是特殊類型的 ZIP 檔案。
computer:/tmp/testdir$ mkdir extracted && unzip contactkeys_candidate.apk -d extracted/
這個步驟會解壓縮組成 APK 的所有檔案。套件名稱和版本位於 APK 的資訊清單中,通常是名為 AndroidManifest.xml 的檔案。
不過,取得的資訊清單檔案是二進位格式,無法供人閱讀。如要將二進位 XML 轉換為使用者可理解的格式,我們會使用先前安裝的 aapt2 工具 (如必要條件一節所述)。
computer:/tmp/testdir$ aapt2 dump badging ./contactkeys_candidate.apk
package: name='com.google.android.contactkeys' versionCode='7805' versionName='1.219.791156583' platformBuildVersionName='Baklava' platformBuildVersionCode='36' compileSdkVersion='36' compileSdkVersionCodename='Baklava'
從上述輸出內容,我們現在可以確定這個 APK 的套件名稱是 com.google.android.contactkeys,版本號碼 (versionCode) 是 1413。
現在,我們將在 APK 中搜尋程式碼透明性簽章。這個檔案應命名為 code_transparency_signed.jwt,並位於 META-INF 資料夾中,與從 APK 擷取的其他檔案放在一起。
computer:/tmp/testdir$ sha256sum extracted/META-INF/code_transparency_signed.jwt
1779a2aee029112c2c9bfc9390b9678f3e5f4595b39705e8528dd522e8042f11 code_transparency_signed.jwt
有了這個雜湊字串,我們現在就擁有所有必要資訊,可根據記錄內容部分說明的格式,組合出記錄酬載。在本例中,對應的記錄酬載應如下所示:
1779a2aee029112c2c9bfc9390b9678f3e5f4595b39705e8528dd522e8042f11
SHA256(Signed Code Transparency JWT)
com.google.android.contactkeys
1143
另請注意,套件版本後方有換行字元。
你可以將內容儲存到檔案,例如 payload.txt。稍後進行納入證明測試時,這項資訊會派上用場。
驗證 APK 程式碼簽章的真實性
現在,我們應該驗證 APK 內嵌程式碼簽章權杖的真實性。為此,我們會使用 bundletool,以及最初用於簽署的金鑰組公開金鑰。這些檔案會發布在各個 APK 的相應區段中。假設您已將公用金鑰憑證 (例如 Android 系統金鑰驗證器) 儲存到名為 signing_cert_pubkey.pem 的檔案,請按照下列指南執行程式碼簽章驗證。
首先,請建立 ZIP 封存檔,然後將候選 APK 新增至 ZIP 封存檔。
computer:/tmp/testdir$ zip -u test.zip contactkeys_candidate.apk
zip warning: test.zip not found or empty
adding: contactkeys_candidate.apk (deflated 58%)
computer:/tmp/testdir$ file test.zip
test.zip: Zip archive data, at least v2.0 to extract, compression method=deflate
我們現在可以使用 bundletool 的 check-transparency 指令,驗證候選 APK 內嵌的程式碼簽章是否與發布的簽章相符。
computer:/tmp/testdir$ java -jar BUNDLETOOL_INSTALL_PATH/bundletool-all-version.jar check-transparency \
--mode=apk \
--apk-zip=test.zip \
--transparency-key-certificate=signing_cert_pubkey.pem
APK signature is valid. SHA-256 fingerprint of the apk signing key certificate (must be compared with the developer's public key manually): D9 E1 73 5B 2A 39 51 27 3A 87 35 B7 66 9E F1 9E F5 3A F1 C1 27 5C BA 31 39 3C 18 40 8B 03 79 D0
Code transparency signature verified for the provided code transparency key certificate.
Code transparency verified: code related file contents match the code transparency file.
請確認上述指令的輸出內容指出「程式碼透明性簽章」和「程式碼透明性」都已通過驗證。如果不是,例如看到 Code transparency verification failed because the provided public key
certificate does not match the transparency file 等輸出內容,表示有問題的 APK 可能已遭入侵,您不應信任該 APK。請務必仔細檢查,確認您是根據正確的公開金鑰憑證驗證這些權杖。如果其他一切正常,這表示您驗證的 APK 程式碼簽章已通過驗證。
驗證套件是否包含在內 (包含證明)
使用先前建構的酬載,您現在可以測試相關套件是否已納入透明度記錄。
Android 開放原始碼計畫的 avb 存放區已發布納入證明工具。如要執行這項指令,請按照下列步驟操作:
computer:external/avb/tools/transparency/verify$ PAYLOAD_PATH=PATH_TO_PAYLOAD_DIR/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=google_1p_code
驗證者會使用對應的檢查點和記錄內容 (位於圖塊目錄),檢查 APK 酬載是否位於透明度記錄中,並驗證 APK 確實是由 Google 發布。
指令輸出內容會寫入 stdout:
OK. inclusion check success!如果記錄中包含套件的程式碼,FAILURE。