App Bundle のコード透明性

コード透明性は、Android App Bundle で公開されるアプリ用のコード署名および検証メカニズムです(使用するかどうかは任意)。このメカニズムでは、アプリ デベロッパーのみが保持するコード透明性署名鍵が使用されます。

コード透明性は、App Bundle と APK で使用される署名スキームとは無関係です。コード透明性鍵は、Play アプリ署名の使用時に Google の安全なインフラストラクチャに格納されるアプリ署名鍵とは異なる別個の鍵です。

コード透明性の仕組み

コード透明性のプロセスは、バンドルがビルドされた後、配信のために Google Play Console にアップロードされる前に、バンドルにコード透明性ファイルを含めることにより機能します。

コード透明性ファイルは、バンドルに含まれている DEX ファイルとネイティブ ライブラリのリスト、およびそれらのハッシュを含む JSON ウェブトークン(JWT)です。さらに、デベロッパーのみが保持するコード透明性鍵で署名されます。

コード透明性の図

コード透明性ファイルは、App Bundle からビルドされたベース APK(具体的には、ベース モジュールのメイン スプリット)に伝播されます。これにより、以下のことを検証できます。

  • APK 内に存在するすべての DEX ファイルおよびネイティブ コード ファイルのハッシュが、コード透明性ファイル内のハッシュと一致する。
  • アプリ内のコード透明性署名鍵の公開鍵コンポーネントが、デベロッパーから提供される公開鍵(デベロッパーが別の安全なチャネルを介して提供する必要がある)と一致する。

この情報の組み合わせにより、APK に含まれるコードがデベロッパーが意図したものであり、変更されていないことが検証されます。

コード透明性ファイルでは、リソース、アセット、Android マニフェスト、lib/ フォルダに含まれている DEX ファイルまたはネイティブ ライブラリ以外のファイルは検証されません。

コード透明性の検証は、デベロッパーとエンドユーザーが、実行するコードがアプリ デベロッパーによって最初にビルドされ、署名されたコードと一致することを確認するための検査のみを目的として使用されます。

既知の制限事項

コード透明性を使用できない場合を以下に示します。

  • アプリのマニフェストで sharedUserId 属性を指定している。このようなアプリは他のアプリとプロセスを共有する可能性があるため、実行するコードについて保証することは困難です。
  • 改ざん対策機能を使用しているアプリや、コード透明性ファイルの生成後にコードを変更するその他のサービスは、コード透明性検証が失敗する原因になります。
  • アプリが API レベル 21 以下(Android 5.0)で従来の Multidex を使用し、かつ機能モジュールを使用している。アプリが Google Play によって Android 5.0 以上のデバイスにインストールされている場合、コード透明性は機能します。それより古い OS バージョンでは、コード透明性は無効になります。

コード透明性を追加する方法

アプリにコード透明性を追加する前に、コード透明性署名に使用できる秘密鍵と公開鍵のペアがあることを確認してください。これは、Play アプリ署名に使用するアプリ署名鍵とは異なる一意の鍵でなければなりません。この鍵を安全に保持し、決して組織外では共有しないでください。

鍵を持っていない場合は、アプリへの署名ガイドの手順に沿って、使用するマシンで鍵を生成できます。コード透明性では標準のキーストア ファイルが使用されるので、鍵生成プロセスはアプリ署名ガイドの手順と同じです。

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 の使用

コード透明性をサポートするには、GitHub からダウンロードできる bundletool バージョン 1.7.0 以降が必要です。

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

アプリのコード透明性を検証する

コード透明性ファイルでコードを検証する方法はいくつかあり、APK が Android デバイスにインストールされるか、ローカルでパソコンにダウンロードされるかによって異なります。

bundletool を使用して App Bundle または APK セットをチェックする

bundletool を使用して、App Bundle または APK セット内のコード透明性を検証できます。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.