Xamarin.FormsでAPKファイルを生成して署名する


Androidアプリを配布するにはAPKファイルに署名が必要とのことなので、Xamarin というか Visual Studio for Mac ではどうすれば良いのか調べてみました。


## まずは挙動を確認

リリースビルドすると...

- `bin/Release` を覗いてみてもAPKファイルは生成されていなかった。 

"発行のためのアーカイブ"を実行すると...

- `$HOME/Library/Developer/Xamarin/Archives/yyyy-mm-dd` にAPKファイルが作成される。 
- `bin/Release` にもAPKファイルが作成される。
- MD5ハッシュ値は両方とも同じだった。

<!--
- "デバッグシンボルファイルが見つからない"的な警告がたくさん出る。
 - "コンパイル"設定で"デバッグ情報"を"なし"にするととりあえず警告はおさまる（リリースビルドでは"なし"にするのが当たり前？）。
-->


## APKの生成と署名

- "発行のためのアーカイブ"を実行
 この時点でAPKファイルが作成されますが、まだ未署名の状態です。

- 生成されたアーカイブを選択して、"署名と配布"をクリック
![sign_1.png](https://qiita-image-store.s3.amazonaws.com/0/169798/79060bee-0bd5-1b83-6b7c-430414192a5a.png "sign_1.png")

- アプリケーション配布方法（ここでは例としてアドホック）を選択
![sign_2.png](https://qiita-image-store.s3.amazonaws.com/0/169798/f86c37e4-8029-6583-30d3-650115592af8.png "sign_2.png")

- "キーの新規作成"をクリック
![sign_3.png](https://qiita-image-store.s3.amazonaws.com/0/169798/20ef3338-547b-7ffa-56c2-63f4a1c227b9.png "sign_3.png")

- 証明書（エイリアス＝キー？）の情報を入力して"OK"をクリック
![sign_4.png](https://qiita-image-store.s3.amazonaws.com/0/169798/9fdb04ad-4753-ab9b-d4c1-4f73d9ed2852.png "sign_4.png")

- キーを選択して"次へ"をクリック
![sign_5.png](https://qiita-image-store.s3.amazonaws.com/0/169798/f073ea34-3bfb-efc0-abba-8c36131bfda6.png "sign_5.png")

 ちなみにキーストアは `$HOME/Library/Developer/Xamarin/Keystore/エイリアス名` の下に作成されていました。
 
```bash
$ ls
BlankAppKey.keyInfo  BlankAppKey.keystore
```

- パスワードを訊かれるので入力して"OK"をクリック
![sign_pass.png](https://qiita-image-store.s3.amazonaws.com/0/169798/da09aa8b-b441-d6b8-8045-1943b05dc583.png "sign_pass.png")

- "発行"をクリック
![sign_6.png](https://qiita-image-store.s3.amazonaws.com/0/169798/4281e56e-2f9a-02e1-81e3-7327bc49e6be.png "sign_6.png")

- APKファイルの保存先を指定して"保存"をクリック
![sign_output.png](https://qiita-image-store.s3.amazonaws.com/0/169798/05433807-bb2a-19f3-fad2-5d872e55f74d.png "sign_output.png")


- おしまい
![sign_7.png](https://qiita-image-store.s3.amazonaws.com/0/169798/779eb99b-b7e3-9cd5-c166-e171e954263c.png "sign_7.png")


## 結果

さて、ちゃんと署名されたかどうか確認してみましょうか。

APKファイルの署名状態は下記のコマンドで確認できるらしいです。

```bash:コマンド
apksigner verify -v [APKファイル]
```

では、確認してみます。

```bash
$ apksigner verify -v ~/Desktop/APKs/com.companyname.BlankApp.apk 
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): false
Number of signers: 1
```

v2署名がされていません...(>_<;

v2署名なしでもアプリのインストールはできるので今のところは問題ないとは思いますが、今後も無効のままにはしておけないのでv2署名を有効にする方策を探らねばなりませんね...
まぁ、Android側でv2署名が必須になれば、それまでにXamarinが対応してくれるでしょうけど。

## 自動で署名

APKファイル作成時に自動で署名できるようです。

Androidプロジェクトの設定から"Androidパッケージへの署名"を選択するとキーストアやらを指定する欄があるので入力します。
キーストアのパスワードを設定した覚えはありませんが、証明書（エイリアス）を作成した時に入力したものがそのまま使われているっぽいです。

![sign_8.png](https://qiita-image-store.s3.amazonaws.com/0/169798/0bbb6ab7-6103-cbab-addb-dd429182c0e5.png "sign_8.png")


"発行のためのアーカイブ"を実行してAPKファイルを作成します。すると...

```bash
$ apksigner verify -v com.companyname.BlankApp.apk
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): false
Number of signers: 1
```

署名済みのAPKファイルが作成されました。

ちなみに署名の設定をせずにAPKファイルを作成した場合はこうなりました。

```bash
$ apksigner verify -v com.companyname.BlankApp.apk
DOES NOT VERIFY
ERROR: Missing META-INF/MANIFEST.MF
```

ということで、XamarinでもAPKファイルに署名できることがわかりました。
とりあえずは以上です。

## おまけ

署名のないアプリをインストールしようとすると...

![install_fail.png](https://qiita-image-store.s3.amazonaws.com/0/169798/c51f1b37-9642-9fb8-291c-3881c4d6e295.png "intall_fail.png")

こうなりました。
「インストールできません」と言って欲しいところです。

署名ありの場合は、こうでした。

![install_success.png](https://qiita-image-store.s3.amazonaws.com/0/169798/99b46268-241e-51c6-598a-9ba9492d9538.png "install_success.png")

私の場合は、v2署名なしでもOreoにインストールできました。メール経由です。
Google Play経由は試してません。



## こちらを参考にしました
apksignerで署名する方法:
http://monozukit.hatenablog.com/entry/2017/01/26/apksigner%E3%81%A7%E7%BD%B2%E5%90%8D%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95