Android アプリ署名: その仕組みと重要な理由
Android スマートフォンにアプリをインストールするたびに、サイレントではあるが重要なセキュリティ チェックがバックグラウンドで行われます。お使いの携帯電話は APK パッケージの デジタル署名 を確認します。この暗号化ハンドシェイクにより、悪意のあるハッカーがアプリをマルウェアで「汚染」するのを防ぎ、開発者がアイデンティティを失わずにアップデートをプッシュできるようにします。
アプリを作成する場合、署名は正しく行う必要があります。 Android をいじりたいだけであれば、これはシステムの中で理解するのが最も満足できる部分の 1 つです。いずれにせよ、アプリ署名の仕組み には時間を費やす価値があります。以下では、テクノロジー、署名スキームがどのように進化したか、オンラインで 証明書を手動で検証する を行う方法について説明します。
- すべての Android アプリに署名が必要な理由と、どのような暗号化が関係しているか (RSA / EC)。
- v1 (JAR)、v2、v3、および v4 署名スキームの違いと、アプリが現在どれを使用する必要があるか。
- Android が署名の継続性に基づいてアップデートを許可するかどうかを決定する方法。
- キーのローテーションにより、開発者が既存のインストールを中断することなく署名キーを変更できるようにする方法。
- コマンドラインまたは ブラウザベースの検証ツール を使用して、APK の署名を自分で検証する方法。
アプリ署名とは何ですか?
アプリ署名の核心は、開発者が 秘密鍵 を使用してアプリのファイルの署名ブロックを生成するプロセスです。対応する 公開鍵 は、META-INF フォルダー内の APK に埋め込まれます。携帯電話がアプリをインストールしようとすると、公開キーを使用して署名がファイルの内容と一致するかどうかを確認します。
これにより、次の 2 つの主要なプロパティが提供されます。
- 不変性: アプリのコードの 1 バイトが (トロイの木馬などによって) 変更された場合、署名はファイルと一致しなくなり、Android はそのインストールを拒否します。
- 身元証明: アプリが既存のアプリを更新しようとする場合、その署名が一致する必要があります。これが、改ざんされた Facebook アプリを公式アプリの上にインストールできない理由です。
署名スキームの進化
Google は、速度とセキュリティの両方を向上させるために署名メカニズムを継続的にアップグレードしてきました。
- V1 (Jar 署名): APK (ZIP) 内の個々のファイルに署名します。 OS がすべてのファイルを解凍してチェックする必要があるため、これには時間がかかります。また、特定の ZIP 操作に対して脆弱です。
- V2 (APK 署名スキーム): APK のバイナリ ブロック全体に署名します。検証のために解凍する必要がないため、驚くほど高速になります。 Android 7.0 (Nougat) で導入されました。
- V3 (キーローテーション): キーの「系統」を追加して V2 を拡張します。これにより、開発者は、新しいキーが古いキーの正規の後継キーであることを証明できます。 Android 9.0 (Pie) で導入されました。
- V4 (ストリーミング署名): 増分インストール用に特別に設計されており、USB または Wi-Fi 経由でダウンロード中にアプリを検証できます。
サイドローディングに証明書が重要な理由
非公式ソースから APK をダウンロードする場合、証明書のハッシュ化 はあなたの親友です。証明書のフィンガープリント (SHA-256 ハッシュなど) は、開発者の署名キーを一意に識別します。各アプリはすべてのアップデートにわたって同じ署名キーを保持するため、APK のフィンガープリントを開発者が公開した値と比較して、それが本物であることを確認できます。
APK が偽物であると疑われる場合は、オンライン APK 検証ツール を通じてそれを実行する必要があります。私たちのツールは以下を表示します:
- 署名者の 通称(CN) (例: 「Android」)。
- 証明書の 有効期間。
- SHA-1/SHA-256 フィンガープリント。
Android がインストール時に署名を検証する方法
「証明書の検証」ステップは無視されることが多いため、APK をタップして Android がそれをインストールするかどうかを決定するときに OS が実際に何を行うのかを詳しく見てみる価値があります。
- APK を ZIP 形式で開き、署名ブロックを見つけます。 v2/v3 署名の場合、中央ディレクトリの直前の構造化ブロックです。レガシー v1 スキームの場合、META-INF/*.RSA、*.DSA、または *.EC の内容です。
- APK の 1 バイトおきの SHA-256 ダイジェストを計算します。 署名ブロックはそれ自体のダイジェストから除外されます。他のものはすべて、定義されたチャンク内でハッシュ化されます。
- 各チャンクのダイジェストを署名ブロックに記録されたダイジェストと照合して検証します。 開発者がファイルに署名してから 1 バイトでも変更されている場合、ダイジェストは一致せず、一般的な「アプリがインストールされていません」エラーでインストールが拒否されます。
- 署名ブロック自体が証明書の秘密キーを使用して生成されたことを確認します。 証明書の公開キーは、ブロック内の暗号署名を確認するために使用されます。 検証に成功した場合、ファイルに署名した人物がこの証明書とペアになった秘密鍵を所有していたことを意味します。
- 証明書のフィンガープリントを、同じパッケージ名の既存のインストールと比較します。 パッケージがすでにインストールされており、新しい APK が別の証明書で署名されている場合、インストールは INSTALL_FAILED_UPDATE_INCOMPATIBLE で拒否されます。これは、OS の主ななりすまし対策です。悪意のある攻撃者は、銀行の署名キーも盗まない限り、銀行アプリを自分のコピーに置き換えることはできません。
これは開発者が信頼できることを証明するものではなく、インストールしようとしているファイルが署名されたものとバイト同一であり、他の者がそれを改ざんしていないことを証明するだけです。開発者を信頼するかどうかは別の決定であり、どのソースからインストールするかを決定することによって決定されます。
「署名の不一致」の本当の意味
サイドローディング時に人々が遭遇する最も一般的な驚きは、更新時の「署名の不一致」エラーです。実際に何が起こっているかは次のとおりです。
- Play ストアから アプリ X バージョン 1.0 がインストールされています。
- Play 以外のソースから アプリ X バージョン 1.1 をダウンロードします。
- OS には同じパッケージ名 (com.example.app) が表示されますが、APK は別の証明書 (元の発行者のものではなく、サイドソースの署名キー) で署名されています。インストールを拒否してしまいます。
これは実際には次の 2 つの方法で起こります。
- サードパーティの APK は 本当に別の出版社からのもの です。たとえば、「MOD が適用された」または「パッチが適用された」コピーです。インストールを拒否するのは正しい動作です。これをインストールするということは、銀行のアプリがすでに触っているのと同じデータを見知らぬ人に託すことを意味する。
- サードパーティの APK は 公式APKの再アップロード ですが、Google の Play アプリ署名システムは、ユーザーの アップロードキー ラッパーを使用して各ユーザーのダウンロードに署名します。 2 つのデバイスでは、同じ概念的なアプリのバージョンに対してわずかに異なる署名データが表示されることがあります。この場合、ルートの証明書のフィンガープリントは依然として一致します。 APK ベリファイア で確認できます。
証明書のフィンガープリント 本当に が既存のインストールと異なる場合、唯一の方法は、置き換えをサイドローディングする前に、まず現在のコピーをアンインストールし (データを失います)、署名検証を決して無効にしないことです。
独自の署名キーの生成 (開発者向け)
Android アプリを構築している場合は、最終的には独自のビルドに署名する必要があります。 Java SDK の keytool を使用する標準の 1 行コマンドは次のとおりです。
keytool -genkeypair -v \
-keystore my-release.keystore \
-alias my-app -keyalg RSA -keysize 2048 \
-validity 10000
知っておくべき 2 つのこと:
- 有効 は重要です。OS は期限切れ間近または期限切れのキーで署名された更新を侵害されたものとして扱うため、10000 日 (約 27 年) が従来の値です。有効期間の長いキーを一度生成して保護します。
- 公開すると、キーを簡単に切り替えることはできません。 v3 署名スキームは、明示的な機能としてキー 回転 を追加します。古い証明書は、保存された証明を通じて新しい証明書を「祝福」し、OS が ID の連続性を維持しながら新しいキーからの更新を受け入れることができるようにします。 v3 を使用しない場合、元のキーを失うことは、既存のインストールがすべて孤立することを意味します。
サイドロードされたテスト ビルドの場合、署名されていないデバッグ キーストアは問題ありません。実稼働環境では、オフライン バックアップに保存された、パスワードで保護された長期有効性のキーストアを使用します。
よくある署名の落とし穴
- 自己署名証明書: ほとんどの Android アプリは自己署名されています。 Web サイトの SSL とは異なり、Android アプリの署名には中央機関がありません。開発者を直接信頼する必要があります。
- デバッグ証明書: テスト用に構築されたアプリは、汎用の「デバッグ」キーを使用します。これらのアプリは決して一般公開すべきではなく、多くのセキュリティ フィルターによってブロックされています。
- キーの紛失: 開発者が秘密キーストアを紛失した場合、次のようなことが起こります。 一度もない アプリを再度更新してください。異なるパッケージ名で「新しい」アプリをリリースする必要があります。
ターゲット SDK に適した署名スキームの選択
アプリの署名は、Android のセキュリティの多くを静かに支えています。秘密キーと公開キーの関係が確立されると、サイドロードされたアプリのメリットを判断し、開発者が署名してからインストールしているものが変更されていないことを確認できます。 Android の内部構造の詳細については、XAPK形式のガイド を参照してください。