アプリケーションへの署名

このドキュメントでは、Android アプリケーションを携帯端末ユーザーに公開する前に署名する方法について説明します。

概要

Android システムでは、インストールするすべてのアプリケーションに対してデジタル署名されて証明書を必要とします。この証明書の秘密鍵は、アプリケーションのデベロッパーが所持するものです。Android システムは証明書をアプリケーションの作成者の識別手段、およびアプリケーション間の信頼関係の確立手段として使用します。証明書は、ユーザーがどのアプリケーションをインストールできるかを制御するものではありません。証明書は認証機関によって署名される必要はありません。通常の Android アプリケーションは自己署名証明書を使用して正常に機能します。

Android アプリケーションの署名について、次の点を理解することが重要です:

  • すべてのアプリケーションは署名される必要があります。署名されていないアプリケーションはシステムにインストールされません。
  • アプリケーションの署名に、自己署名証明書を使用できます。認証機関は不要です。
  • アプリケーションをエンド ユーザーにリリースする準備ができたら、適切な秘密鍵を使用してアプリケーションに署名する必要があります。SDK ツールで生成されたデバッグ キーで署名されたアプリケーションは、公開できません。
  • システムが署名証明書の有効期限を確認するのは、インストール時のみです。アプリケーションのインストール後に署名者証明書が期限切れになった場合、アプリケーションは正常な動作を継続します。
  • 標準ツールである Keytool と Jarsigner を使用してキーを生成し、アプリケーションの .apk ファイルに署名できます。

Android システムは、適切に署名されていないアプリケーションをインストールせず、実行もしません。この規則は、実際のデバイスでもエミュレータでも、Android システムが実行されるすべての状況で適用されます。このため、エミュレータまたはデバイス上で実行またはデバッグする前に、アプリケーションの署名を設定する必要があります。

Android SDK ツールは、デバッグ時のアプリケーション署名を支援します。「ADT Plugin for Eclipse」と「Ant ビルド ツール」では両方とも、デバッグ モードリリース モードの 2 種類の署名モードを利用できます。

  • 開発およびテスト中は、デバッグ モードでコンパイルできます。デバッグ モードでは、ビルド ツールは JDK に付属の Keytool ユーティリティを使用して、キーストアとキーを既知のエイリアスとパスワードで作成します。コンパイルのたびに、ツールはデバッグ キーを使用してアプリケーションの .apk ファイルに署名します。パスワードは既知のものなので、コンパイルのたびにツールにキーストア/キー パスワードを入力する必要はありません。
  • アプリケーションをリリースする準備ができたら、リリース モードでコンパイルして、.apk に秘密鍵で署名する必要があります。次の 2 通りの方法があります:
    • Keytool と Jarsigner をコマンド ラインで使用する方法。このアプローチでは、まずアプリケーションを署名されていない .apk にコンパイルします。次に、Jarsigner(または類似のツール)を使用して秘密鍵で .apk に手動で署名します。適切な秘密鍵を所持していない場合は、Keytool を手動で実行して独自のキーストア/キーを生成し、Jarsigner でアプリケーションに署名できます。
    • ADT Export Wizard を使用する方法。ADT プラグイン搭載の Eclipse を使用して開発している場合、Export Wizard を使用してアプリケーションをコンパイルし、秘密鍵を生成して(必要な場合)、.apk に署名できます。この作業をすべて Export Wizard を使用して 1 つのプロセスで実行できます。

署名戦略

アプリケーションの署名は、開発アプローチに一部影響します。特に、複数のアプリケーションをリリースする予定の場合、高い影響を与えます。

一般に、すべてのデベロッパーに推奨される戦略は、アプリケーションの予期される使用期間を通じて同じ証明書ですべてのアプリケーションに署名することです。このようにするには、複数の理由があります:

  • アプリケーションのアップグレード - アプリケーションのアップグレードをリリースするとき、ユーザーが新バージョンにシームレスにアップグレードできるように、アップグレードされたアプリケーションにも同じ証明書で署名します。システムがアプリケーションのアップデートをインストールする際は、新バージョンの証明書のいずれかが旧バージョンの証明書と一致する場合、システムがアップデートを許可します。一致する証明書を使用せずに署名する場合は、アプリケーションに別のパッケージ名を割り当てる必要があります。この場合、新しいバージョンがまったく新しいアプリケーションとしてインストールされます。
  • アプリケーションのモジュール性 - Android システムでは、アプリケーションが要求する場合、同じ証明書で署名されたアプリケーションを同じプロセスで実行できます。これにより、システムはこれらを単一のアプリケーションとして取り扱います。このようにすればアプリケーションをモジュールとして配備でき、ユーザーは必要に応じて各モジュールを個別に更新できます。
  • 許可によるコード/データ共有 - Android システムでは、署名ベースの権限付与を実施しているため、アプリケーションは指定された証明書で署名されている別のアプリケーションに機能を提供できます。同じ証明書で複数のアプリケーションに署名し、署名に基づいた権限のチェックを行うことで、アプリケーションはコードとデータを安全な方法で共有できます。

署名戦略を決定する際のもう 1 つの重要な検討事項として、アプリケーションの署名に使用するキーの有効期間の設定方法があります。

  • アプリケーションのアップグレードをサポートするには、キーの有効期間は、アプリケーションの予定される試用期間以上である必要があります。有効期間は、25年以上であることが推奨されます。キーの有効期間が切れた場合、ユーザーはアプリケーションの新バージョンにシームレスにアップグレードできなくなります。
  • 同じキーで複数の異なるアプリケーションに署名する場合、キーの有効期間が、今後のアプリケーション スイートに追加される依存アプリケーションを含め、すべてのアプリケーションのすべてのバージョンの予定される使用期間を超えることを確認してください。
  • アプリケーションを Android マーケットに公開する予定の場合、アプリケーションの署名に使用するキーの有効期間を、2033 年 10 月 22 日以降の期限に設定する必要があります。マーケット サーバーは、新バージョンが公開されたときにユーザーがマーケット アプリケーションをシームレスにアップグレードできるよう、この要件を義務付けています。

アプリケーションの設計時にこれらの点を考慮し、アプリケーションの署名に適切な証明書を使用してください。

署名の基本設定

キーストアとデバッグ キーの生成をサポートするため、SDK ビルド ツールで Keytool を使用できることを初めに確認してください。たいていの場合、「JAVA_HOME」環境変数を設定して適切な JDK を参照させることで、SDK ビルド ツールで Keytool を認識できます。または、JDK バージョンの Keytool を PATH 変数に追加しても認識できます。

Linux バージョンに付属されている GNU Java コンパイラで開発している場合は、gcj バージョンではなく、JDK バージョンの Keytool を使用していることを確認してください。Keytool が既に PATH に指定されている場合は、/usr/bin/keytool の symlink を指していることがあります。この場合は、symlink ターゲットが JDK の Keytool を指していることを確認してください。

アプリケーションを公開する場合は、Jarsigner ツールをコンピュータで使用できるようにする必要があります。Jarsigner と Keytool の両方が JDK によって提供されます。

デバッグ モードでの署名

Android ビルド ツールにはデバッグ署名モードがあり、アプリケーションの開発とデバッグがスムーズに行えます。また、.apk をエミュレータまたはデバイスにインストールする際の、署名に対する Android システム要件を満たします。デバッグモードでは、SDK ツールは Keytool を呼び出してデバッグ キーストアとキーを作成します。

SDK ツールは事前に指定された名前とパスワードを使用してデバッグ キーストア/キーを作成します。

  • キーストア名 – 「debug.keystore」
  • キーストアのパスワード – 「android」
  • キーのエイリアス – 「androiddebugkey」
  • キーのパスワード – 「android」
  • CN – 「CN=Android Debug,O=Android,C=US」

必要に応じて、デバッグ キーストア/キーの場所および名前を変更できます。また、自分で作成したデバッグ キーストア/キーを指定することもできます。Eclipse/ADT で、[[]ウィンドウ(Windows)] > [[]設定(Prefs)] > [[]Android] > [[]ビルド(Build)] を選択します。ただし、自分で作成したデバッグ キーストア/キーは、デフォルトのデバッグ キー(上述)と同じキーストア/キー名とパスワードを使用する必要があります。

注: デバッグ証明書で署名した場合は、アプリケーションを公開できません

Eclipse ユーザー

Eclipse/ADT で開発し、Keytool を上記のように設定してある場合は、デバッグモードにおける署名はデフォルトで有効になっています。アプリケーションを実行またはデバッグするときに、ADT は .apk にデバッグ証明書で署名し、エミュレータにインストールします。ADT が Keytool にアクセスできる場合は、ユーザーは特に操作する必要はありません。

Ant ユーザー

Ant を使用して .apk ファイルを構築する場合、デバッグ署名モードは debug オプションを使用することで有効になります(android ツールで生成された build.xml ファイルを使用していることが前提となります)。ant debug を実行してアプリケーションをコンパイルする際、ビルド スクリプトはキーストア/キーを生成し、.apk に署名します。ユーザーは操作する必要はありません。詳細は、その他の統合開発環境での開発: デバッグモードにおけるビルド をお読みください。

デバッグ証明書の有効期限

デバッグ モード(Eclipse/ADT と Ant ビルドのデフォルト)でのアプリケーション署名に使用した自己署名証明書には、作成日から 365 日の有効期限が設定されます。

証明書の期限が切れると、ビルド エラーが発生します。Ant ビルドでは、エラーは次のようになります:

debug:
[echo] Packaging bin/samples-debug.apk, and signing it with a debug key...
[exec] Debug Certificate expired on 8/4/08 3:43 PM

Eclipse/ADT では、Android コンソールに同様のエラーが表示されます。

この問題を解決するには、debug.keystore ファイルを削除します。AVD のデフォルトの格納場所は、OS X と Linux の場合は ~/.android/avd、Windows XP の場合は C:\Documents and Settings\\.android\、Windows Vista の場合は C:\Users\\.android\ です。

次にビルドを行うと、ビルド ツールは新しいキーストアとデバッグ キーを再度生成します。

開発コンピュータがグレゴリオ暦以外のロケールを使用している場合、ビルド ツールが誤って期限切れのデバッグ証明書を生成することがあります。このため、アプリケーションをコンパイルしようとするとエラーが発生します。解決策については、トラブルシューティング トピックの ビルド ツールが期限切れのデバッグ証明書を生成するため、アプリケーションがコンパイルできない をご覧ください。

公開リリースへの署名

アプリケーションを他のユーザーに公開する準備ができたら、次のことを行う必要があります:

  1. アプリケーションをリリース モードでコンパイルする
  2. 適切な秘密鍵を取得する
  3. アプリケーションに秘密鍵で署名する

以下のセクションでは、これらの手順を実行する方法について説明します。

ADT プラグイン搭載の Eclipse を使用している場合、これらの手順を実行する代わりに Export Wizard を使用して .apk をコンパイルして秘密鍵で署名できます。Export Wizard では、処理過程で新しいキーストアと秘密鍵の生成も可能です。Eclipse ADT によるコンパイルと署名を参考にコンパイルを行ってください。

リリース向けのコンパイル

アプリケーションのリリースを準備するには、リリース モードでコンパイルする必要があります。リリース モードでは、Android ビルド ツールはアプリケーションを通常どおりにコンパイルしますが、デバッグ キーで署名しません。

注: 署名されていないアプリケーション、またはデバッグ キーで署名されたアプリケーションはリリースできません。

Eclipse ユーザー

署名されていない .apk ファイルを Eclipse からエクスポートするには、パッケージ エクスプローラー(Package Explorer)でプロジェクトを右クリックして、[[]Android ツール(Android Tools)] > [[]署名されていないアプリケーション パッケージのエクスポート(Export Unsigned Application Package)] を選択します。次に、署名されていない .apk ファイルの場所を指定します(または、AndroidManifest.xml ファイルを Eclipse で開き、[[]概要(Overview)] タブを開いて [[]署名されていない .apk のエクスポート(Export an unsigned .apk)] をクリックします)。

Export Wizard では、コンパイルと署名の手順を一緒に処理できます。Eclipse ADT によるコンパイルと署名をご覧ください。

Ant ユーザー

Ant を使用している場合は、必要な作業は Ant コマンドでビルド ターゲットとして「release」を指定するだけです。たとえば、Ant を build.xml ファイルがあるディレクトリから実行している場合、コマンドは次のようになります:

$ ant release

ビルド スクリプトは、アプリケーション .apk を署名せずにコンパイルします。

適切な秘密鍵の取得

アプリケーションの署名を準備するには、まず署名に使用する適切な秘密鍵があることを確認することが必要です。適切な秘密鍵とは、次の条件を満たすものです:

  • 自分が所有している。
  • アプリケーションで識別される、個人、法人、または組織の実体を表す。
  • アプリケーションまたはアプリケーション スイートの予期される使用期間を超える有効期間を持っている。有効期間として、25 年以上を推奨します。

    アプリケーションを Android マーケットに公開する予定の場合、2033 年 10 月 22 日までの有効期間が必要です。有効期間がこの日付以前に期限切れになるキーで署名されたアプリケーションは、アップロードできません。

  • Android SDK ツールで生成されたデバッグ キーではない。

自己署名されたキーを使用できます。適切なキーがない場合、Keytool を使用して生成する必要があります。基本設定で説明した手順に従って、Keytool を使用できるようにしてください。

Keytool で自己署名キーを生成するには、keytool コマンドを使用して以下に示すオプション(および、必要に応じてその他のオプション)を渡します。

注: Keytool を実行する前に、秘密鍵のセキュリティ設定を読んで、キーのセキュリティを確保する方法と、自分とユーザーにとってセキュリティ確保が重要な理由を理解してください。特に、自分のキーを生成する場合、キーストアとキーの両方に強力なパスワードを選択する必要があります。

Keytool のオプション 説明
-genkeyキー ペアを生成します(公開キーと秘密鍵)。
-v詳しいメッセージを出力する。
-keystore <keystore-name>.keystore秘密鍵を含むキーストアの名前。
-storepass <password>

キーストアのパスワード。

セキュリティ上の注意として、安全なコンピュータで作業している場合を除き、このオプションをコマンド ラインに指定しないでください。指定しなかった場合、Keytool からパスワードの入力が求められます。このため、パスワードはシェルの履歴に記録されません。

-alias <alias_name>キーのエイリアス。
-keyalg <alg>キーの生成時に使用する暗号化アルゴリズム。DSA と RSA の 2 つをサポートしています。
-dname <name>

キーの作成者を識別する、識別名。値は、自己署名証明書の発行者およびサブジェクト フィールドとして使用されます。

このオプションはコマンド ラインで指定する必要はありません。指定しなかった場合、Jarsigner からそれぞれの識別名フィールド(CN、OU など)の入力が求められます。

-validity <valdays>

キーの有効期間(日数)。

注: 10000 以上の値を推奨します。

-keypass <password>

キーのパスワード。

セキュリティ上の注意として、安全なコンピュータで作業している場合を除き、このオプションをコマンド ラインに指定しないでください。指定しなかった場合、Keytool からパスワードの入力が求められます。このため、パスワードはシェルの履歴に記録されません。

秘密鍵を生成する Keytool コマンドの例を示します。

$ keytool -genkey -v -keystore my-release-key.keystore
-alias alias_name -keyalg RSA -validity 10000

上記のコマンド例を実行すると、Keytool からキーストアとキーのパスワードと、キーの識別名フィールドの指定が求められます。キーストアが my-release-key.keystore というファイルとして生成されます。キーストアとキーは、入力したパスワードで保護されます。キーストアには 1 つのキーが含まれ、10000 日間有効です。エイリアスは、後で使用する名前で、アプリケーションに署名するときにこのキーストアを参照する名前です。

Keytool の詳細は http://java.sun.com/j2se/1.5.0/docs/tooldocs/#security のドキュメント(英語のみ)をご覧ください。

アプリケーションの署名

リリースする .apk に実際に署名する準備ができたら、Jarsigner ツールを使用して署名できます。基本設定で説明したように、Jarsigner をコンピュータで使用できることを確認してください。また、秘密鍵を含むキーストアがあることも確認してください。

アプリケーションに署名するには、Jarsigner を実行して、アプリケーションの .apk と、.apk の署名に使用する秘密鍵を含むキーストアの両方を参照します。以下の表では、使用できるオプションを示します。

Jarsigner のオプション 説明
-keystore <keystore-name>.keystore秘密鍵を含むキーストアの名前。
-verbose詳しいメッセージを出力する。
-storepass <password>

キーストアのパスワード。

セキュリティ上の注意として、安全なコンピュータで作業している場合を除き、このオプションをコマンド ラインに指定しないでください。指定しなかった場合、Jarsigner からパスワードの入力が求められます。このため、パスワードはシェルの履歴に記録されません。

-keypass <password>

秘密鍵のパスワード。

セキュリティ上の注意として、安全なコンピュータで作業している場合を除き、このオプションをコマンド ラインに指定しないでください。指定しなかった場合、Jarsigner からパスワードの入力が求められます。このため、パスワードはシェルの履歴に記録されません。

Jarsigner を使用して my_application.apk というアプリケーション パッケージに署名する例を、上記で作成したキーストアを使用して示します。

$ jarsigner -verbose -keystore my-release-key.keystore
my_application.apk alias_name

上記のコマンドを実行すると、Jarsigner からキーストアとキーのパスワードの入力が求められます。.apk がその場で変更され、.apk は署名されます。.apk に別のキーで複数回署名できます。

.apk が署名されたことを確認するには、次のようなコマンドを使用できます:

$ jarsigner -verify my_signed.apk

.apk が適切に署名されると、Jarsigner から「jar verified」と出力されます。詳細情報が必要な場合は、次のコマンドを使用できます。

$ jarsigner -verify -verbose my_application.apk

または、次のコマンドを使用します。

$ jarsigner -verify -verbose -certs my_application.apk

上記の -certs オプションが付加されたコマンドでは、「CN=」行が出力され、キーの作成者が示されます。

注: 「CN=Android Debug」と出力される場合、.apk が Android SDK によって生成されたデバッグ キーで署名されたことを示しています。アプリケーションをリリースする予定の場合は、デバッグ キーではなく秘密鍵で署名する必要があります。

Jarsigner の詳細は http://java.sun.com/j2se/1.5.0/docs/tooldocs/#security のドキュメント(英語のみ)をご覧ください。

Eclipse ADT によるコンパイルと署名

ADT 搭載 Eclipse を使用している場合、Export Wizard を使用して署名済み .apk をエクスポートできます(必要に応じて、新しいキーストアを作成することもできます)。Export Wizard は、Keytool と Jarsigner のすべての処理を、コマンド ラインを使用せず、グラフィカル ユーザー インターフェースで署名を実行できます。Export Wizard は Keytool と Jarsigner の両方を使用するため、上記の署名の基本設定の条件を満たすコンピュータで使用できます。

署名された .apk を作成するには、パッケージ エクスプローラー(Package Explorer)でプロジェクトを右クリックして、[[]Android ツール(Android Tools)] > [[]署名済みアプリケーション パッケージのエクスポート(Export Signed Application Package)] を選択します(または、AndroidManifest.xml ファイルを Eclipse で開き、[[]概要(Overview)] タブを開いて [[]Export Wizard を使用する(Use the Export Wizard)] をクリックします)。表示されたウィンドウには、アプリケーションのエクスポート中に見つかったエラーが表示されます。エラーが見つからなかった場合は Export Wizard で処理を続行します。.apk に署名する秘密鍵の選択や、新しいキーストアと秘密鍵の作成など、アプリケーション署名のプロセスを手順を追って実行できます。

Export Wizard が完了すると、配布可能な署名済み .apk が作成されています。

秘密鍵のセキュリティ設定

秘密鍵のセキュリティ設定は、作成者とユーザーの両者にとって重要です。他人にキーを使用させたり、第三者が見つけて使用できるような安全ではない場所にキーストアとキーを放置したりすると、作成者とユーザー間の信頼が損なわれます。

他者が許可を得ずにキーを取得した場合、その人物はアプリケーションに署名して配布し、本物のアプリケーションを故意に置き換えたり破損させたりすることができます。このような人物は、身元を詐称してアプリケーションに署名して配布し、その他のアプリケーションまたはシステム自体を攻撃したり、ユーザー データを破損させたり盗み出したりすることもあります。

キーの有効期限が切れるまで、秘密鍵のセキュリティを常に適切に維持できるかは、デベロッパーとしての評価を左右します。キーを安全に保つためのヒントをいくつか紹介します。

  • キーストアとキーに強力なパスワードを選択します。
  • Keytool でキーを生成するとき、コマンド ラインで -storepass および -keypass オプションを指定しないようにします。指定すると、パスワードがシェル履歴に記録され、コンピュータのすべてのユーザーがアクセスできるようになります。
  • 同様に、Jarsigner でアプリケーションに署名するとき、コマンド ラインで -storepass-keypass オプションを指定しないようにします。
  • 秘密鍵を誰にも与えたり貸したりせず、不正なユーザーにキーストアとキーのパスワードを知られないようにします。

一般的には、キーの生成、使用、保管に関して常識的な注意を払っていれば、セキュリティを確保することができます。