「程式碼透明性」是可選用的程式碼簽署和驗證機制,適用於使用 Android App Bundle 發布的應用程式。它採用程式碼透明性簽名金鑰,由應用程式開發人員專門保管。
程式碼透明性與應用程式套件和 APK 所使用的簽名配置無關。程式碼透明性金鑰是獨立的,不同於使用 Play 應用程式簽署功能儲存在 Google 安全基礎架構的應用程式簽署金鑰。
程式碼透明性的運作方式
該程序會在建構完成後加入套件中的程式碼透明性檔案,然後再上傳到 Play 管理中心進行發布。
程式碼透明性檔案為 JSON Web Token (JWT),其中包含 DEX 檔案清單及位於套件中的原生資料庫及其雜湊。接著,使用程式碼透明性金鑰簽名,該金鑰僅供開發人員持有。
此程式碼透明性檔案已全面套用至透過應用程式套件建立的基本 APK (尤其是基礎模組的主要分割區域)。接著系統會驗證以下項目:
- APK 中顯示的所有 DEX 和原生程式碼檔案與程式碼透明性檔案中擁有相符的雜湊。
- 應用程式中,程式碼透明性的簽名金鑰的公開金鑰元件與開發人員的公開金鑰相符 (必須由開發人員透過獨立、安全的管道提供)。
此資訊會驗證 APK 中的程式碼是否與開發人員的預期相符,且未遭到修改。
程式碼透明性檔案不會驗證資源、資產、Android 資訊清單,或者不屬於 DEX 檔案或 lib/
資料夾中的原生資料庫的任何檔案。
程式碼透明性驗證僅用於開發人員和使用者的檢查作業,他們想確保自己執行的程式碼與應用程式開發人員最初建立及簽署的程式碼相符。
已知限制
在下列情況下,無法使用程式碼透明性:
- 在資訊清單中指定
sharedUserId
屬性的應用程式。這類應用程式可能會與其他應用程式共用程序,因此難以保證所執行的程式碼。 - 如果應用程式使用防竄改功能或其他在產生程式碼透明性檔案後變更程式碼的服務,會導致程式碼透明性驗證失敗。
- 使用 API 級別 21 以下 (Android 5.0) 的舊版 Multidex 並採用功能模組的應用程式。使用者透過 Google Play Android 5.0 以上版本裝置安裝應用程式時,程式碼透明性會繼續運作。較舊的 OS 版本將停用程式碼透明性。
如何導入程式碼透明性機制
在應用程式中導入程式碼透明性機制之前,請確認您已擁有私人及公開金鑰組,可用於程式碼透明性的簽署認證。這組金鑰應不同於您用於 Play 應用程式簽署的應用程式簽署金鑰,該金鑰必須妥善保存,決不能與機構外部人士分享。
如果您沒有金鑰,請按照「簽署應用程式」指南中的操作說明,在電腦上產生一組金鑰。程式碼透明性會使用標準 keystore 檔案,因此即使這份指南僅適用於應用程式簽署,金鑰產生的程序也相同。
使用 Android Gradle 外掛程式
程式碼透明性支援需要 Android Gradle 外掛程式 7.1.0-alpha03 及以上版本。若要設定簽署程式碼透明性所用的金鑰,請在 bundle
區塊中新增以下內容。
Groovy
// In your app module's build.gradle file: android { ... bundle { codeTransparency { signing { keyAlias = "ALIAS" keyPassword = "PASSWORD" storeFile = file("path/to/keystore") storePassword = "PASSWORD" } } ... } }
Kotlin
// In your app module's build.gradle.kts file: android { ... bundle { codeTransparency { signing { keyAlias = "ALIAS" keyPassword = "PASSWORD" storeFile = file("path/to/keystore") storePassword = "PASSWORD" } } ... } }
所使用的金鑰必須僅用於程式碼透明性,而非 Play 應用程式簽署所使用的應用程式簽署金鑰。
在指令列中使用 bundletool
若要支援程式碼透明性需要 bundletool 1.7.0 及以上版本,您可以從 GitHub 下載。
執行下列指令,為 Android App Bundle 新增程式碼透明性。所使用的金鑰必須僅用於程式碼透明性,而非 Play 應用程式簽署所使用的應用程式簽署金鑰。
bundletool add-transparency \
--bundle=/MyApp/my_app.aab \
--output=/MyApp/my_app_with_transparency.aab \
--ks=/MyApp/keystore.jks \
--ks-pass=file:/MyApp/keystore.pwd \
--ks-key-alias=MyKeyAlias \
--key-pass=file:/MyApp/key.pwd
或者,如果想要使用自己的簽名工具,可以使用 bundletool 產生未簽署的程式碼透明性檔案,在獨立環境中簽署,然後將簽章插入該套件中:
# Generate code transparency file
bundletool add-transparency \
--mode=generate_code_transparency_file \
--bundle=/MyApp/my_app.aab \
--output=/MyApp/code_transparency_file.jwt \
--transparency-key-certificate=/MyApp/transparency.cert
# Add code transparency signature to the bundle
bundletool add-transparency \
--mode=inject_signature \
--bundle=/MyApp/my_app.aab \
--output=/MyApp/my_app_with_transparency.aab \
--transparency-key-certificate=/MyApp/transparency.cert \
--transparency-signature=/MyApp/signature
驗證應用程式的程式碼透明性
有不同的方法可以根據程式碼透明性檔案驗證程式碼,作法取決於您的 Android 裝置是否安裝了 APK 或是下載到電腦本機上。
使用 Bundletool 檢查應用程式套件或 APK 組合
您可以在應用程式套件或 APK 組合中,使用 Bundletool 驗證程式碼透明性。使用 check-transparency
指令列印公開憑證指紋:
# For checking a bundle:
bundletool check-transparency \
--mode=bundle \
--bundle=/MyApp/my_app_with_transparency.aab
No APK present. APK signature was not checked.
Code transparency signature is valid. SHA-256 fingerprint of the code transparency key certificate (must be compared with the developer's public key manually): 01 23 45 67 89 AB CD EF ..
Code transparency verified: code related file contents match the code transparency file.
# For checking a ZIP containing app's APK splits:
bundletool check-transparency \
--mode=apk \
--apk-zip=/MyApp/my_app_with_transparency.zip
APK signature is valid. SHA-256 fingerprint of the apk signing key certificate (must be compared with the developer's public key manually): 02 34 E5 98 CD A7 B2 12 ..
Code transparency signature is valid. SHA-256 fingerprint of the code transparency key certificate (must be compared with the developer's public key manually): 01 23 45 67 89 AB CD EF ..
Code transparency verified: code related file contents match the code transparency file.
您也可以選擇性地指定要用於驗證套件或 APK 組合的公開憑證,如此一來,您就不必手動比對雜湊:
bundletool check-transparency \
--mode=bundle \
--bundle=/MyApp/my_app_with_transparency.aab \
--transparency-key-certificate=/MyApp/transparency.cert
No APK present. APK signature was not checked.
Code transparency signature verified for the provided code transparency key certificate.
Code transparency verified: code related file contents match the code transparency file.
bundletool check-transparency \
--mode=apk \
--apk-zip=/MyApp/my_app_with_transparency.zip \
--apk-signing-key-certificate=/MyApp/apk.cert \
--transparency-key-certificate=/MyApp/transparency.cert
APK signature verified for the provided apk signing key certificate.
Code transparency signature verified for the provided code transparency key certificate.
Code transparency verified: code related file contents match the code transparency file.
使用 Bundletool 檢查裝置上安裝的應用程式
如要檢查已安裝在 Android 裝置上的應用程式,請確認該裝置已透過 ADB 連接至電腦,並作出以下指令:
bundletool check-transparency \
--mode=connected_device \
--package-name="com.my.app"
APK signature is valid. SHA-256 fingerprint of the apk signing key certificate (must be compared with the developer's public key manually): 02 34 E5 98 CD A7 B2 12 ..
Code transparency signature is valid. SHA-256 fingerprint of the code transparency key certificate (must be compared with the developer's public key manually): 01 23 45 67 89 AB CD EF ..
Code transparency verified: code related file contents match the code transparency file.
連線裝置透明性檢查也可以選擇性地為您指定的公開金鑰驗證簽名:
bundletool check-transparency \
--mode=connected-device \
--package-name="com.my.app" \
--apk-signing-key-certificate=/MyApp/apk.cert \
--transparency-key-certificate=/MyApp/transparency.cert
APK signature verified for the provided apk signing key certificate.
Code transparency signature verified for the provided code transparency key certificate.
Code transparency verified: code related file contents match the code transparency file.