apkファイルに署名するまでの流れ
apkファイルに署名するまでの流れをざっくり書きます。
- 非公開鍵を格納するキーストアファイルと、そこに格納する非公開鍵(キー)を生成する。
- 生成したキーストアファイルと、非公開鍵(キー)を使い、apkファイルに署名をする。
#1. 非公開鍵を格納するキーストアファイルと、そこに格納する非公開鍵(キー)を生成する。
キーストアと、キーを生成する
下記のコマンドでキーストアと、キーを生成します。
rintaro$ keytool -genkey -v \
> -keystore hoge.keystore \
> -storepass pass_keystore \
> -alias alias_key1 \
> -keypass pass_key1 \
> -keyalg RSA \
> -validity 10
*Windowsの方は、^
で改行できるかと。
keytool のオプション説明
JAVA Documentation | keytool - 鍵と証明書の管理ツールを参考にしました。
- v
- 「冗長」モードで実行され、詳細な証明書情報が出力される。
- genkeypair(旧名 genkey)
- 鍵のペア (公開鍵および関連する非公開鍵) を生成する。
- keystore
- キーストアの場所を指定する。指定しなければ.keystoreという名前のデフォルトキーストアファイルが、ユーザのホームディレクトリに作成される。(.keystoreがすでにある場合は、それを使う)
- storepass
- キーストアのパスワードを指定する。
- alias
- キーストアに保存するキーの名前(エイリアス)を指定する。
- keypass
- キーのパスワードを指定する。
- keyalg
- 鍵のペアを生成するのに使うアルゴリズムを指定する。
- validity
- 証明書の有効日数を指定する。
コマンドを実行すると、下記のようにいくつか聞かれたのですが、全て空白のままenterして、最後だけy
を入力しました。
姓名は何ですか。
[Unknown]:
組織単位名は何ですか。
[Unknown]:
組織名は何ですか。
[Unknown]:
都市名または地域名は何ですか。
[Unknown]:
都道府県名または州名は何ですか。
[Unknown]:
この単位に該当する2文字の国コードは何ですか。
[Unknown]:
CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknownでよろしいですか。
[いいえ]: y
10日間有効な2,048ビットのRSAの鍵ペアと自己署名型証明書(SHA256withRSA)を生成しています
ディレクトリ名: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
[hoge.keystoreを格納中]
生成したキーストアの内容を確認する
rintaro$ keytool -list -v \
> -keystore hoge.keystore \
> -storepass pass_keystore
コマンドを実行すると、キーストアの情報と、そこに格納されているキーの情報が表示されるかと思います。
ここまでが、冒頭で書いた「1.非公開鍵を格納するキーストアファイルと、そこに格納する非公開鍵(キー)を生成する。」になります。
2.生成したキーストアファイルと、非公開鍵(キー)を使い、apkファイルに署名をする。
apkファイルに署名する
下記のコマンドで、apkファイルに署名をします。
rintaro$ jarsigner -verbose \
> -keystore hoge.keystore \
> -storepass pass_keystore \
> -keypass pass_key1 \
> android-release-unsigned.apk \
> alias_key1
jarsignerオプションの説明
JAVA Documentation | jarsignerを参考にしました。
- verbose
- 冗長モードで動作し、JARの署名または検証の進行状況に関する追加情報を出力する。
- keystore
- キーストアの場所を示すURLを指定する。検証の際は必要ない。
- storepass
- キーストアのパスワードを指定する。
- keypass
- キーのパスワードを指定する。
コマンドを実行すると、下記が表示されました。
更新中: META-INF/MANIFEST.MF
追加中: META-INF/ALIAS_KE.SF
追加中: META-INF/ALIAS_KE.RSA
署名中: AndroidManifest.xml
署名中: assets/www/cordova-js-src/android/nativeapiprovider.js
署名中: assets/www/cordova-js-src/android/promptbasednativeapi.js
署名中: assets/www/cordova-js-src/exec.js
署名中: assets/www/cordova-js-src/platform.js
署名中: assets/www/cordova-js-src/plugin/android/app.js
署名中: assets/www/cordova.js
署名中: assets/www/cordova_plugins.js
署名中: assets/www/css/index.css
署名中: assets/www/img/logo.png
署名中: assets/www/index.html
署名中: assets/www/js/index.js
署名中: classes.dex
署名中: res/drawable-land-hdpi-v4/screen.png
署名中: res/drawable-land-ldpi-v4/screen.png
署名中: res/drawable-land-mdpi-v4/screen.png
署名中: res/drawable-land-xhdpi-v4/screen.png
署名中: res/drawable-land-xxhdpi-v4/screen.png
署名中: res/drawable-land-xxxhdpi-v4/screen.png
署名中: res/drawable-port-hdpi-v4/screen.png
署名中: res/drawable-port-ldpi-v4/screen.png
署名中: res/drawable-port-mdpi-v4/screen.png
署名中: res/drawable-port-xhdpi-v4/screen.png
署名中: res/drawable-port-xxhdpi-v4/screen.png
署名中: res/drawable-port-xxxhdpi-v4/screen.png
署名中: res/mipmap-hdpi-v4/icon.png
署名中: res/mipmap-ldpi-v4/icon.png
署名中: res/mipmap-mdpi-v4/icon.png
署名中: res/mipmap-xhdpi-v4/icon.png
署名中: res/mipmap-xxhdpi-v4/icon.png
署名中: res/mipmap-xxxhdpi-v4/icon.png
署名中: res/xml/config.xml
署名中: resources.arsc
jarは署名されました。
警告:
署名者の証明書は6か月以内に期限切れになります。
-tsaまたは-tsacertが指定されていないため、このjarにはタイムスタンプが付加されていません。タイムスタンプがないと、署名者証明書の有効期限(2018-02-25)後または将来の失効日後に、ユーザーはこのjarを検証できない可能性があります。
署名はできているっぽいのですが、警告が気になるので調べたところ、こちらのサイトを発見。
書いてある通り-tsa http://timestamp.digicert.com
オプションを追加して実行してみたところ、うまく行きました。
実行と、その結果は下記になります。
rintaro$ jarsigner -verbose \
> -tsa http://timestamp.digicert.com \
> -keystore hoge.keystore \
> -storepass pass_keystore \
> -keypass pass_key1 \
> android-release-unsigned.apk \
> alias_key1
更新中: META-INF/ALIAS_KE.SF
シグネチャ・タイムスタンプのリクエスト
TSAの場所: http://timestamp.digicert.com
更新中: META-INF/ALIAS_KE.RSA
署名中: AndroidManifest.xml
署名中: assets/www/cordova-js-src/android/nativeapiprovider.js
署名中: assets/www/cordova-js-src/android/promptbasednativeapi.js
署名中: assets/www/cordova-js-src/exec.js
署名中: assets/www/cordova-js-src/platform.js
署名中: assets/www/cordova-js-src/plugin/android/app.js
署名中: assets/www/cordova.js
署名中: assets/www/cordova_plugins.js
署名中: assets/www/css/index.css
署名中: assets/www/img/logo.png
署名中: assets/www/index.html
署名中: assets/www/js/index.js
署名中: classes.dex
署名中: res/drawable-land-hdpi-v4/screen.png
署名中: res/drawable-land-ldpi-v4/screen.png
署名中: res/drawable-land-mdpi-v4/screen.png
署名中: res/drawable-land-xhdpi-v4/screen.png
署名中: res/drawable-land-xxhdpi-v4/screen.png
署名中: res/drawable-land-xxxhdpi-v4/screen.png
署名中: res/drawable-port-hdpi-v4/screen.png
署名中: res/drawable-port-ldpi-v4/screen.png
署名中: res/drawable-port-mdpi-v4/screen.png
署名中: res/drawable-port-xhdpi-v4/screen.png
署名中: res/drawable-port-xxhdpi-v4/screen.png
署名中: res/drawable-port-xxxhdpi-v4/screen.png
署名中: res/mipmap-hdpi-v4/icon.png
署名中: res/mipmap-ldpi-v4/icon.png
署名中: res/mipmap-mdpi-v4/icon.png
署名中: res/mipmap-xhdpi-v4/icon.png
署名中: res/mipmap-xxhdpi-v4/icon.png 署名中: res/mipmap-xxxhdpi-v4/icon.png
署名中: res/xml/config.xml
署名中: resources.arsc
jarは署名されました。
警告:
署名者の証明書は6か月以内に期限切れになります。
署名できているか確認する
次のコマンドで、署名ができているかを確認できます。
jarsigner -verify -verbose -keystore <署名に使用したkeystoreのパス> -certs <apkファイル名>
jarsigner -verify -verbose -keystore ./hoge.keystore -certs ./hoge.apk
実行すると、次のようなログが出力され、署名できていることを確認できました。
s k 3505 Fri Feb 16 13:45:18 JST 2018 META-INF/MANIFEST.MF
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
3649 Fri Feb 16 13:45:18 JST 2018 META-INF/ALIAS_KE.SF
1370 Fri Feb 16 13:45:18 JST 2018 META-INF/ALIAS_KE.RSA
smk 2708 Fri Nov 30 00:00:00 JST 1979 AndroidManifest.xml
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 1322 Fri Nov 30 00:00:00 JST 1979 assets/www/cordova-js-src/android/nativeapiprovider.js
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 1441 Fri Nov 30 00:00:00 JST 1979 assets/www/cordova-js-src/android/promptbasednativeapi.js
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 11143 Fri Nov 30 00:00:00 JST 1979 assets/www/cordova-js-src/exec.js
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 4924 Fri Nov 30 00:00:00 JST 1979 assets/www/cordova-js-src/platform.js
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 4005 Fri Nov 30 00:00:00 JST 1979 assets/www/cordova-js-src/plugin/android/app.js
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 72748 Fri Nov 30 00:00:00 JST 1979 assets/www/cordova.js
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 210 Fri Nov 30 00:00:00 JST 1979 assets/www/cordova_plugins.js
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 3719 Fri Nov 30 00:00:00 JST 1979 assets/www/css/index.css
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 21814 Fri Nov 30 00:00:00 JST 1979 assets/www/img/logo.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 2513 Fri Nov 30 00:00:00 JST 1979 assets/www/index.html
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 1664 Fri Nov 30 00:00:00 JST 1979 assets/www/js/index.js
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 143720 Fri Nov 30 00:00:00 JST 1979 classes.dex
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 216014 Fri Nov 30 00:00:00 JST 1979 res/drawable-land-hdpi-v4/screen.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 41538 Fri Nov 30 00:00:00 JST 1979 res/drawable-land-ldpi-v4/screen.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 90490 Fri Nov 30 00:00:00 JST 1979 res/drawable-land-mdpi-v4/screen.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 488469 Fri Nov 30 00:00:00 JST 1979 res/drawable-land-xhdpi-v4/screen.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 674457 Fri Nov 30 00:00:00 JST 1979 res/drawable-land-xxhdpi-v4/screen.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 832779 Fri Nov 30 00:00:00 JST 1979 res/drawable-land-xxxhdpi-v4/screen.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 220338 Fri Nov 30 00:00:00 JST 1979 res/drawable-port-hdpi-v4/screen.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 41064 Fri Nov 30 00:00:00 JST 1979 res/drawable-port-ldpi-v4/screen.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 90555 Fri Nov 30 00:00:00 JST 1979 res/drawable-port-mdpi-v4/screen.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 501006 Fri Nov 30 00:00:00 JST 1979 res/drawable-port-xhdpi-v4/screen.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 692467 Fri Nov 30 00:00:00 JST 1979 res/drawable-port-xxhdpi-v4/screen.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 919644 Fri Nov 30 00:00:00 JST 1979 res/drawable-port-xxxhdpi-v4/screen.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 5217 Fri Nov 30 00:00:00 JST 1979 res/mipmap-hdpi-v4/icon.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 2230 Fri Nov 30 00:00:00 JST 1979 res/mipmap-ldpi-v4/icon.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 3202 Fri Nov 30 00:00:00 JST 1979 res/mipmap-mdpi-v4/icon.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 6794 Fri Nov 30 00:00:00 JST 1979 res/mipmap-xhdpi-v4/icon.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 8901 Fri Nov 30 00:00:00 JST 1979 res/mipmap-xxhdpi-v4/icon.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 10963 Fri Nov 30 00:00:00 JST 1979 res/mipmap-xxxhdpi-v4/icon.png
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 2436 Fri Nov 30 00:00:00 JST 1979 res/xml/config.xml
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
smk 3384 Fri Nov 30 00:00:00 JST 1979 resources.arsc
X.509, CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown (alias_key1)
[証明書は18/02/25 17:12に失効します]
s=シグネチャが検証されました
m=エントリがマニフェスト内にリストされます
k=1つ以上の証明書がキーストアで検出されました
i=1つ以上の証明書がアイデンティティ・スコープで検出されました
- 署名者: "CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown"
ダイジェスト・アルゴリズム: SHA-256
署名アルゴリズム: SHA256withRSA、2048ビット鍵
jarが検証されました。
警告:
このjarには、署名者の証明書が6か月以内に期限切れとなるエントリが含まれています。
これで、署名付きのAPKファイルの作成が完了しました!