Android: Debug Keystore と Release Keystore をコマンドから生成する

デバッグ用署名とリリース用署名を生成するコマンドまとめ。

## keytool バージョン

keytool は JDK のバージョンに依存します。本記事は JDK 17 環境を想定しています。

Android Studio Arctic Fox 2020.3.1 時点では Android Studio にバンドルされている JDK は JDK 11 です。

JDK 16 以上の　keytool で署名鍵を作成すると、Android Studio (JDK11) からのビルド・署名時に以下のエラーが発生します。

```
Integrity check failed: java.security.NoSuchAlgorithmException: Algorithm HmacPBESHA256 not available
```

これは、JDK 16 から keytool が PKCS12 形式で鍵を生成する際に PBES2 SHA256 形式を用いるようになったが、PBES2 SHA256 は JDK 12 以上でしか対応しておらず、JDK 11 では読み取れないためです。

[Upgraded the Default PKCS12 Encryption and MAC Algorithms](https://www.oracle.com/java/technologies/javase/16-relnotes.html)

JDK 16 以上のkeytool で JDK 11 互換の keystore を生成するには `-J-Dkeystore.pkcs12.legacy` オプションを追加します。


また、[JDK 9 以降の keytool では storetype はデフォルトで PKCS12 となっています](http://openjdk.java.net/jeps/229)が、JDK 8 以前では storetype JKS がデフォルトになっているため、JDK 8 keytool では `-storetype pkcs12` オプションを追加してください。

## Debug 署名

debug.keystore を生成します。

```shell
% keytool -J-Dkeystore.pkcs12.legacy -genkey -v -keystore debug.keystore -keyalg RSA -validity 10950 -storepass android -alias androiddebugkey -dname "CN=Android Debug, O=Android, C=US"
```

| 項目 | 値 |
| --- | --- |
| Algorithm | 2048bit RSA |
| Validity | 10950 (30年) |
| Keystore type | PKCS12 |
| Keystore password | android |
| Alias name | androiddebugkey |
| Alias password | android |
| Domain name | CN=Android Debug, O=Android, C=US |

* debug.keystore は上記の項目はすべて指定されたとおりに生成する必要があります
* PKCS12 (p12) 形式が推奨されています
* PKCS12 形式では Keystore password と Alias password は同一になります

## Debug 署名の使い道

* チームで同一の debug.keystore 署名で開発したい場合に共通の debug.keystore を git リポジトリへ含めて設定しておくと便利です

## Release (Google Play Signing Upload) 署名

release.keystore を生成します。

```shell
keytool -J-Dkeystore.pkcs12.legacy -genkey -v -keystore release.keystore -keyalg RSA -storepass {Keystore password} -alias {Alias name} -validity 9125 -dname "CN={CommonName}, O={OrganizationName}, S={StateName}, C={Country}"
```

| 項目 | 値 |
| --- | --- |
| Algorithm | 2048bit RSA |
| Validity | 9125 (25年) |
| Keystore type | PKCS12 |
| Keystore password | {任意のパスワード} |
| Alias name | {任意のエイリアス名} |
| Alias password | {Keystore password と同一のものが設定されます} |
| Domain CN | CommonName = 人の通称, おすすめは "Developer" など |
| Domain O | OrganizationName = 組織名称, アプリを所有・公開する組織の英語表記 |
| Domain S | StateName = 州名・地方名, "Tokyo" など |
| Domain C | Country = 国名, "Japan" など |

* validity は 10950 (30年) でも問題ありませんが、公式ドキュメントでは 25 年となっていたので 25 年を設定しています

https://developer.android.com/studio/publish/app-signing#generate-key

Domain name のルールは以下のドキュメントを参照。

https://docs.oracle.com/javase/jp/6/technotes/tools/solaris/keytool.html#DName

## Release (Google Play Signing Upload) 署名の使い道

* Release 署名は Google Play Signing を使用してください
* Google Play Signing 用の Upload Key は手元で生成します

https://developer.android.com/studio/publish/app-signing#enroll

## 生成した Keystore の確認

debug.keystore / release.keystore の確認

```shell
% keytool -list -v -keystore debug.keystore -storepass android
```

コマンドの出力を英語表記にする

```shell
% keytool -J-Duser.language=en -list -v -keystore debug.keystore -storepass android
```

## JKS 形式を PKCS12 形式へ変換する

```shell
keytool -J-Dkeystore.pkcs12.legacy -v -importkeystore -srckeystore release.keystore -srcalias {Alias name} -srcstorepass {Source Keystore password} -srckeypass {Source Alias password} -destkeystore release.keystore.p12 -deststoretype PKCS12 -storepass {New Keystore password}  
```

* PKCS12 形式の Alias password は Keystore password と同一のものが設定されます