Androidの署名について（releaseバリアントでビルドする）

Androidの署名の仕組みについて調べたことをまとめます。
ローカルで`release`バリアントをビルドするところまでで、Play Storeへのリリースまでは扱いません。

内容は基本的に公式ドキュメントのまとめです。
https://developer.android.com/studio/publish/app-signing?hl=ja

Android Studioのバージョンは`3.2`です。

## 署名の意味
公開キー証明書（電子証明書）には、公開キーおよび、キーの所有者を特定するメタデータ情報が含まれている。
APKに署名すると、公開キー証明書がAPKにアタッチされる。公開キー証明書は指紋の役割を果たすため、以降のAPKのアップデートが元の作成者からリリースされたことが確認できる。

## デバッグ用証明書
Android Studioでアプリを実行すると、Android Studioがデバッグ用証明書を生成し、自動でAPKに署名する。
デバッグ用証明書と証明書作成に使用された秘密キーは以下に保存されている。

```
~/.android/debug.keystore
```

## リリース用証明書の作成と、自動で署名してアプリを実行する方法
`release`バリアントでアプリを起動しようとすると、以下のエラーが表示される。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/dcd61165-9013-ec11-01f5-84d4f258d8ab.png)

```
Error: The apk for your currently selected variant (app-release.apk) is not signed. Please specify a signing configuration for this variant (release).
```

これは、`release`バリアントに署名設定がされていないために起こるエラーである。

なお、`debug`バリアントは特別で、Android Studioによって自動で署名が行われるようになっていて、署名設定の編集もできない。

> Android Studio はデバック用署名情報を署名の設定に自動的に保存するため、デバッグのたびに入力する必要はありません。...デバッグ用署名の設定を直接編集することはできません

### キーストアの生成
署名に必要なキーストアの生成は、`Build > Generate Signed Bundle / APK`メニューから行う。

`APK`を選択して次へ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/5fe33800-5bb8-c0b5-a350-d84bed99e14e.png)

`Create new...`をクリック。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/4691ce65-86ba-0c2a-efd0-831ae5627408.png)

キーストアの情報を入力する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/20fad35c-5fbd-dfc5-509e-22a16e526e7a.png)

- `Key store path`: キーストアの保存場所を指定する。あんまりよくわかってないが、ファイル拡張子は`jks`にすると良さそう。
- `Password`: キーストアのパスワード。署名設定時に必要になる。キーストアの中身を確認する際にも使用する。
- `Key > Alias`: キーの名前。署名設定時に必要になる。
- `Key > Password`: キーのパスワード。署名設定時に必要になる。
- `Key > Validity (years)`: デフォルトのままにしておいた。
- `Key > Certificate`: どれか一つ入力が必要なので、名前だけ入れておく。

入力したら`OK`をクリックする。

これでキーストアが作成されたので、`Cancel`をクリックしてウィザードを終了する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/df6696c8-e7e4-bc1f-f086-871394856dd5.png)

キーストアの中身は以下のコマンドで確認できる。
キーストアのパスワードを聞かれるので、先程設定したものを入力する。

```
$ keytool -v -list -keystore ~/Desktop/android.jks
キーストアのパスワードを入力してください:
キーストアのタイプ: JKS
キーストア・プロバイダ: SUN

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

別名: key0
作成日: Dec 11, 2018
...
```

### releaseバリアントの署名設定
`release`バリアントに署名設定を行う。
`File > Project Structure`メニューの`Signing`タブで新しい署名設定を作成する。
先程作成したキーストアの情報に合わせる。
`Key Password`と`Store Password`の位置がさっきの画面と逆なので注意（ここで少しハマった...）。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/576c5ba0-abd7-3e09-23c6-75edd90d8fe7.png)

`Build Types`タブで`release`を選択し、`Signing Config`に先程作成した署名設定（ここでは`config`）を指定する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/e51cef0d-aa17-dc29-a96a-d77b7be1e77a.png)

ここまでできたら、`Build Variants`ウィンドウで`release`バリアントを指定してアプリを実行できる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/0f45de9a-5b9f-da41-315a-38b506fd3907.png)

署名設定は、`build.gradle`ファイルに反映されているのでわかりやすい（パスワードが丸見えなので、環境変数化するとか必要）。

```gradle
android {
    signingConfigs {
        // 署名設定
        config {
            keyAlias 'key0'
            keyPassword 'S853OEW2'
            storeFile file('/Users/user/Desktop/android.jks')
            storePassword 'zsAU2hbV'
        }
    }
    ...
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.config  // 署名設定
        }
    }
}
```