Androidのキーストアから証明書をエクスポートする

業務でAndroid開発をしていて、都合上、後から鍵ペアを人に渡さなければいけない場合があります。

新しいapkのたびにキーストアファイルを作っているのなら、別にそれごと渡してしまえばいいのですが、自分用のキーストアに作ってしまった場合、キーストアごと渡すわけにはいきません。

そこでキーストアファイルから証明書をエクスポートして相手に渡すことを考えますが、apkに署名するには、証明書の他に秘密鍵が必要です。

先に結論だけ書いておきます。keytoolコマンドのimportkeystoreを使います。

> keytool -importkeystore -srckeystore .\mykeystore.jks -srcstorepass <<自分のキーストアのパスワード>> -destkeystore app1.jks -deststorepass <<新規作成するキーストアのパスワード>> -deststoretype jks -srcalias app1
<app1> の鍵パスワードを入力してください。

これでapp1.jksというキーストアファイルが新規作成され、自分のキーストアの中から特定のエイリアスの鍵ペアだけをコピーできます。

以下は説明です。

例えば自分用のキーストアの中身がこうなっていたとします。

> keytool -list -v -keystore .\mykeystore.jks -storepass <<キーストアのパスワード>>

キーストアのタイプ: JKS
キーストアのプロバイダ: SUN

キーストアには 2 エントリが含まれます。

別名: app1
作成日: 2012/03/08
エントリタイプ: PrivateKeyEntry
証明連鎖の長さ: 1
証明書[1]:
所有者: C=JP
発行者: C=JP
シリアル番号: 4f582f00
有効期間の開始日: Thu Mar 08 00:00:00 JST 2012 終了日: Wed Jul 10 00:00:00 JST 3011
証明書のフィンガープリント:
         MD5:  00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
         SHA1: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
         署名アルゴリズム名: SHA1withRSA
         バージョン: 3


*******************************************
*******************************************


別名: app2
作成日: 2012/03/08
エントリタイプ: PrivateKeyEntry
証明連鎖の長さ: 1
証明書[1]:
所有者: C=JP
発行者: C=JP
シリアル番号: 4f57f300
有効期間の開始日: Thu Mar 08 00:00:00 JST 2012 終了日: Wed Jul 10 00:00:00 JST 3011
証明書のフィンガープリント:
         MD5:  00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
         SHA1: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
         署名アルゴリズム名: SHA1withRSA
         バージョン: 3

証明書のエクスポートとインポートは以下のコマンドでできますが、秘密鍵がエクスポートできません。

> keytool -exportcert -keystore .\mykeystore.jks -storepass <<キーストアのパスワード>> -alias app1 -file .\app1.cer
証明書がファイル <.\app1.cer> に保存されました。

> keytool -import -keystore app1.jks -storepass <<新規作成するキーストアのパスワード>> -file .\app1.cer
所有者: C=JP
発行者: C=JP
シリアル番号: 4f582f00
有効期間の開始日: Thu Mar 08 00:00:00 JST 2012 終了日: Wed Jul 10 00:00:00 JST 3011
証明書のフィンガープリント:
         MD5:  00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
         SHA1: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
         署名アルゴリズム名: SHA1withRSA
         バージョン: 3
この証明書を信頼しますか? [no]:  yes
証明書がキーストアに追加されました。

この状態のキーストアはこうなっています。

> keytool -v -list -keystore .\app1.jks -storepass <<キーストアのパスワード>>

キーストアのタイプ: JKS
キーストアのプロバイダ: SUN

キーストアには 1 エントリが含まれます。

別名: app1
作成日: 2012/03/31
エントリのタイプ: trustedCertEntry

所有者: C=JP
発行者: C=JP
シリアル番号: 4f582f00
有効期間の開始日: Thu Mar 08 00:00:00 JST 2012 終了日: Wed Jul 10 00:00:00 JST 3011
証明書のフィンガープリント:
         MD5:  00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
         SHA1: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
         署名アルゴリズム名: SHA1withRSA
         バージョン: 3


*******************************************
*******************************************

エントリのタイプがtrustedCertEntryになっています。このエントリでapkを署名しようとするとjarsignerがエラーを出します。

jarsigner: 次の証明連鎖が見つかりません: app1。  app1 は、非公開鍵および対応する公開鍵証明連鎖を含む有効な KeyStore 鍵エントリを参照する必要があります。
(英語の場合)
jarsigner: Certificate chain not found for: app1.  app1 must reference a valid KeyStore key entry containing a private key and corresponding public key certificate chain.

Eclipseの場合は、何も言われず、Finishボタンが押せません。

ここで最初の結論のところで書いたimportkeystoreを使って、キーストアからキーストアへのインポートをすることで、秘密鍵を持ったまま新しいキーストアに証明書をコピーできます。コピー後のキーストアファイルはこうなります。

> keytool -list -v -keystore .\app1.jks -storepass <<キーストアのパスワード>>

キーストアのタイプ: JKS
キーストアのプロバイダ: SUN

キーストアには 1 エントリが含まれます。

別名: app1
作成日: 2012/04/01
エントリタイプ: PrivateKeyEntry
証明連鎖の長さ: 1
証明書[1]:
所有者: C=JP
発行者: C=JP
シリアル番号: 4f582f00
有効期間の開始日: Thu Mar 08 00:00:00 JST 2012 終了日: Wed Jul 10 00:00:00 JST 3011
証明書のフィンガープリント:
         MD5:  00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
         SHA1: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
         署名アルゴリズム名: SHA1withRSA
         バージョン: 3

エントリタイプがPrivateKeyEntryになっていれば、通常通りapkの署名に使えます。

あと、importkeystoreが使えるのはJDK6以降のようなので、バージョンは確認してください。


タグ: ,

新しく会社作りました!

コメント / トラックバック 1 件

  1. […] アプリを複数のメンバで開発していて、開発者ごとに別々のキーストアを使用していると、証明書が異なるAPKファイルは上書きインストールできないので、一旦削除してからインストールすることになります。また、Googleマップを使用する場合のAPIキーの取得に証明書が必要で、結果APIキーも開発者ごとに異なってしまいます。これでは手間がかかるので、複数のメンバで開発する場合はキーストアを共用するのがいいでしょう。Eclipseメニューの「ウィンドウ」→「設定」→左ペイン「Android」→「ビルド」とした右ペインの「カスタム・デバッグ・キーストア」欄に共通のキーストアを指定します。(参考サイト:開発用署名 debug.keystore、Androidにおけるセキュリティ設計と動作(前編)、Androidのキーストアから証明書をエクスポートする) […]

コメントをどうぞ