Google サービス アプリケーションの透明性に関する完全な確認

このページでは、Android デバイスにインストールされている APK または APEX が、 請求者モデルに記載されているクレームに対応していることを確認する方法について説明します。このプロセスでは、デバイスから APK をプルし、抽出したアーティファクトに対してログ包含証明を行います。

検証プロセス

透明性ログは、ハッシュで構成される Merkle ツリーを使用して実装されます。 リーフノードにはデータが含まれ、親ノードには子ノードのハッシュが含まれます。

包含証明と整合性証明という 2 つの基本的な計算により、透明性ログの改ざん防止プロパティが検証されます。 包含証明では、ログに特定の APK バージョンのエントリが含まれていることを確認します。 このログエントリには、デバイスにインストールされている APK ファイルの SHA256 ダイジェストであるハッシュが含まれています。 整合性証明では、新しいエントリが追加されたときに、新しいチェックポイントがツリーの以前のバージョンと暗号的に整合していること(またはツリーが改ざんされていないこと)を確認します。 このガイドでは、包含証明を計算するプロセスに焦点を当て、最新のチェックポイントに対する整合性証明を継続的に行うために証人に依存します。

対象の APK を検証するには、証人付きチェックポイントに対して包含証明を行います。 このログは、標準化された証人プロトコルを使用して、公開証人ネットワークと統合する予定です。 この統合により、証人付きチェックポイントが提供され、ログの整合性が保証されます。

デバイス上の Google アプリが請求者モデルに記載されているクレームに準拠していることを確認するには、次の手順を行います。

包含証明

デバイス上の対象の APK がログに含まれていることを確認するには、APK を抽出してハッシュを計算し、包含証明を使用して、そのハッシュが公開されたチェックポイントに存在するかどうかを確認します。包含証明が成功すると、脅威モデルに記載されているリスクに対する保証が得られ、アプリが正当な Google アプリであることが確認されます。

ログ内の APK 包含を確認する方法

Google のファーストパーティ アプリであると主張するアプリは、このログに対して検証できます。

認定の前提条件

アーティファクト(ファームウェアまたは APK)がクレームに準拠していることを確認する前に、ネットワークに接続されたパソコンで次のツールが使用可能であることを確認してください。 検証対象によっては、すべてが必要でない場合があります。

Golang

検証ツール は Go で記述されています。ビルドするには、Go サイトから Go 1.24 以降をインストールします。 Go サイトからインストールします。

Android Debug Bridge(ADB)

ADB は、Android デバイスと通信してイメージを検査したり、 APK を抽出したりするツールです。Android SDK Platform Tools のウェブサイトで入手できます。

包含証明検証ツール

包含証明検証ツールは、透明性ログにクエリを実行し、アーティファクトがログに含まれているかどうかを出力する 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 Asset Packaging Tool)は、Android アプリのリソースのコンパイルとパッケージ化に使用されるビルドツールです。 Android SDK Build Tools バージョン 26.0.2 以降では、スタンドアロン ツールとして提供されています。

bundletool

bundletool は、Android App Bundle(AAB)のビルドに使用されるツールです。APK コード署名の検証にも使用できます。 GitHub からダウンロードできます。

wget または curl

wgetcurl は、インターネットからファイルを取得またはダウンロードするために使用できるツールです。 検証スクリプトでこれらのツールが使用される可能性があるため、いずれかのツールがインストールされていることを確認してください。

Avbtool

avbtool は、ファクトリー イメージの VBMeta ダイジェストの計算と バイナリの検証に使用されます。 (包含証明検証ツールのセクションで説明したように)avb リポジトリのクローンを作成すると、クローンされた avb ディレクトリ内に avbtool.py があります。このディレクトリを $PATH 環境変数に追加する必要があります。

computer:~$ PATH=$PATH:DIRECTORY_CONTAINING_AVBTOOL

Fbpacktool

fbpacktool は、Pixel の個々のコンポーネントを解凍するために使用される Python スクリプトです。 bootloader.img。 APK を検証する場合は必要ありません。 このツールは、avbtool.py が検証に必要なイメージを検出できるようにするために重要です。

このツールを使用するには、次の 3 つの 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 自体から派生した情報を使用してログペイロードを構築する必要があります。

開始する前に、デバイスで USB デバッグを有効にしてadb 接続を許可します。

次に、デバイスにインストールされている APK を見つけます。このガイドでは、 Google Play 開発者サービスの APKcom.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

この出力は、デバイスに 1 つのベース APK と複数の 分割 APK がインストールされています com.google.android.gms。 分割 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

検証ツールは、チェックポイントとログの内容( tile ディレクトリから)を使用して、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 値は、パッケージが透明性ログに対して暗号的に検証され、ログのクレームに準拠していることを示します。