このページでは、Android デバイスにインストールされている APK が Claimant Model で行われたクレームに対応していることを確認するためのさまざまな方法について説明します。これには、問題の APK をデバイスから取得し、コードの整合性をチェックして、抽出されたアーティファクトでログ包含証明を実行することが含まれます。
確認プロセス
透明性ログは、ハッシュで構成される Merkle ツリーで実装されます。リーフノードにはデータが含まれ、親ノードには子ノードのハッシュが含まれます。
基本的には、マークルツリーに対して 2 つの計算(包含証明と整合性証明)を実行して、透明性ログの改ざん防止プロパティを検証します。前者は、ログに特定の APK バージョンに対応するエントリが含まれていることを証明します。ログエントリには、ハッシュが含まれています。これは、JSON Web Token(JWT)形式のコード署名トークンの SHA256 ダイジェストです。対応する APK から取得できます。後者は、新しいエントリがツリーに追加されたときに、新しいチェックポイントがツリーの以前のバージョンと(暗号的に)整合性があることを証明します。
対象の APK を検証するには、目撃されたチェックポイントに基づいて包含証明テストを実施します。このログは、標準化された証人プロトコルを使用して、公開証人ネットワークと統合する予定です。これにより、ログの一貫性が保証される目撃チェックポイントが提供されます。
デバイス上の APK が請求者モデルの主張に準拠していることを確認したい場合は、以下の記事を参照してください。
インクルージョン証明
Android ユーザーは、まず APK とその関連メタデータを抽出し、再計算したルートハッシュを公開されたチェックポイントに含まれるルートハッシュと比較することで、デバイス上の対象 APK がログに含まれていることを確認できます。一致した場合、Android ユーザーは脅威モデルに記載されている保護を確実に受けられます。
ログで APK の包含を確認する方法
前述のように、現在対象となっている APK のリストは、概要ページで確認できます。
検証の前提条件
デバイスから抽出した APK が Google の主張と一致していることを確認する前に、ネットワークに接続されたパソコンから次のツールをインストールする必要があります。
Android Debug Bridge(ADB)
ADB は Android デバイスと通信するツールで、Android SDK Platform Tools のウェブサイトで入手できます。
AAPT2
AAPT2(Android Asset Packaging Tool)は、Android アプリのリソースのコンパイルとパッケージ化に使用されるビルドツールです。Android SDK Build Tools 26.0.2 以上でスタンドアロン ツールとして見つけることができます。
bundletool
bundletool は、Android App Bundle(AAB)のビルドに使用されるツールです。また、デバイスにインストールできる APK に AAB を変換するためにも使用できます。これは GitHub からダウンロードできます。
インクルージョン証明の検証ツール
これは、Android オープンソース プロジェクト(AOSP)内の avb という名前の git リポジトリで公開した Go モジュールです。Google システム サービス APK の透明性ログをクエリし、パッケージがログに含まれているかどうかを出力できます。この使用例については、後のセクションをご覧ください。
このツールをダウンロードするには、まず avb リポジトリのクローンを作成する必要があります。
computer:~$ git clone https://android.googlesource.com/platform/external/avb
検証ツールのソースコードは、avb リポジトリ内の tools/transparency/verify にあります。
検証用のペイロードを作成する
デバイスから抽出した 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 がデバイスにインストールされている場合、上記のコマンドは、デバイスのインストール場所を示すパスを返します。それ以外の場合は、出力は表示されません。
次に、次のコマンドを使用して、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 内でコード透明性署名を検索します。APK から抽出された他のファイルとともに META-INF フォルダ内に含まれる code_transparency_signed.jwt という名前のファイルである必要があります。
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_system_apk
検証ツールは、対応するチェックポイントとログの内容(タイル ディレクトリにあります)を使用して、APK ペイロードが透明性ログにあることを確認し、Google によって公開されたことを検証します。
コマンドの出力は stdout に書き込まれます。
OK. inclusion check success!(パッケージのコードがログに含まれている場合)、FAILURE。