このページでは、Android デバイスにインストールされている APK または APEX が、請求者モデルの申し立てに対応していることを確認する方法について説明します。このプロセスでは、デバイスから APK を取得し、抽出されたアーティファクトでログ包含証明を行います。
確認プロセス
透明性ログは、ハッシュで構成される Merkle ツリーで実装されます。リーフノードにはデータが含まれ、親ノードには子ノードのハッシュが含まれます。
2 つの基本的な計算(包含証明と整合性証明)により、透明性ログの改ざん防止特性が検証されます。包含証明は、ログに特定の APK バージョンのエントリが含まれていることを確認します。このログエントリには、デバイスにインストールされている APK ファイルの SHA256 ダイジェストであるハッシュが含まれています。整合性証明により、新しいエントリが追加されたときに、新しいチェックポイントがツリーの以前のバージョンと暗号的に整合性が保たれていること(またはツリーが改ざんされていないこと)が保証されます。このガイドでは、包含証明の計算プロセスに焦点を当て、最新のチェックポイントに対して整合性証明を継続的に実行する証人に依存しています。
対象の APK を検証するには、目撃されたチェックポイントに対して包含証明を実行します。このログは、標準化された証人プロトコルを使用して、公開証人ネットワークと統合する予定です。この統合により、目撃されたチェックポイントが提供され、ログの整合性が保証されます。
デバイス上の Google アプリが請求者モデルの請求に準拠していることを確認するには、次の手順に沿って操作します。
インクルージョン証明
デバイス上の対象 APK がログに含まれていることを確認するには、APK を抽出し、そのハッシュを計算して、包含証明を使用して、そのハッシュが公開されたチェックポイントに存在するかどうかを確認します。包含証明が成功すると、脅威モデルに記載されているリスクに対する保証が提供され、アプリが正当な Google アプリであることが確認されます。
ログで APK の包含を確認する方法
Google のファーストパーティ アプリを主張するアプリは、このログに対して検証できます。
検証の前提条件
抽出した APK を検証する前に、次のツールをパソコンにインストールする必要があります。
Android Debug Bridge(ADB)
ADB は Android デバイスと通信するツールで、Android SDK Platform Tools のウェブサイトで入手できます。
AAPT2
AAPT2(Android Asset Packaging Tool)は、Android アプリのリソースをコンパイルしてパッケージ化するために使用されるビルドツールです。Android SDK Build Tools 26.0.2 以上でスタンドアロン ツールとして利用できます。
Golang
検証ツールは Go で記述されています。ビルドするには、Go サイトから Go 1.17 以降をインストールします。
インクルージョン証明の検証ツール
verifier という名前の Go モジュールを android-binary-transparency GitHub リポジトリで公開しています。このツールは、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 に 1 つのベース 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
これで、ログ コンテンツのセクションで説明されている形式でログ ペイロードを構築するために必要な情報がすべて揃いました。結果からハッシュを 1 つ選択すると(すべての分割 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 アプリの数によっては、各アプリを列挙して個別に包含証明を行うのは面倒な場合があります。
Google では、デバイスに現在インストールされているすべてのパッケージを検出して測定できる Uraniborg という別の自動ツールも提供しています。出力は verifier ツールに直接送られるため、デバイス上のすべてのアプリの透明性を 1 つのステップで確認できます。
この自動ワークフローを使用するには、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 は、パッケージが透明性ログに対して暗号的に検証され、ログのクレームに準拠していることが確認されたことを示します。