2016/12/27

未署名の apk に後から署名する方法

未署名の apk に署名するツールは、build-tools 24.0.3 以降から `jarsigner` の代わりに `apksigner` を使うようになりました。
`zipalign` の実行順序など細かいところが変わっていますのでご注意ください。

なお、署名済みの apk を未署名にする方法は以下を参照してください。

> 参考
> - [署名済みの apk から署名を削除する方法 | 穀風](http://kokufu.blogspot.jp/2016/12/apk_27.html)


### Overview
全体の流れとしては以下のようになります。

- zip のアライメント調整
- 署名
- 検証

具体的には以下。

```console
$ zipalign -v -p 4 my-app-unsigned.apk my-app-unsigned-aligned.apk
$ apksigner sign --ks ~/.android/my-key.jks --ks-key-alias alias-name --out my-app.apk my-app-unsigned-aligned.apk
$ apksigner verify my-app.apk
```

`apksigner` と `zipalign` は `android-sdk/build-tools/XX.X.X/` にあり、ここではパスが通ってることとします実際には、build-tools のバージョン指定があってパスを通すのは結構面倒。

> 参考
>
> - [アプリに署名する | Android Studio](https://developer.android.com/studio/publish/app-signing.html#signing-manually)
> - [android - how to sign an already compiled APK - Stack Overflow](http://stackoverflow.com/questions/10930331/how-to-sign-an-already-compiled-apk)

一度経験すれば上記で十分だと思いますが、一応各手順の説明を書いておきます。


### zipalign
署名する前に zip のアライメントを整える必要がありますbuild-tools 24.0.2 以前の `zipalign` は `jarsigner` の実行以降に行っていたが、`apksigner` は実行前に行うとのこと。

```console
`gutter: false;
$ zipalign -v -p 4 my-app-unsigned.apk my-app-unsigned-aligned.apk
```

- `-v` 冗長な情報表示
- `-p` 全ての共有ファイルで同じアライメントを使う
- `4` アライメント [byte]、少なくとも現在は 4 固定

> 参考
> - [zipalign | Android Studio](https://developer.android.com/studio/command-line/zipalign.html)


### 署名
署名ファイル `my-key.jks` は既に作成済みとします。作成方法は参考リンクを参照してください上のほうに Android Studio での作成方法も書いてあります。

```console
$ apksigner sign --ks ~/.android/my-key.jks --ks-key-alias alias-name --out my-app.apk my-app-unsigned-aligned.apk
```

`--out` を指定しなかった場合、元のファイルに上書きされます。
他の項目は自明ということで。

> 参考
> - [アプリに署名する | Android Studio](https://developer.android.com/studio/publish/app-signing.html#signing-manually)
> - [apksigner | Android Studio](https://developer.android.com/studio/command-line/apksigner.html)


### 検証
最後に `apksigner` を利用して検証します。

```console
$ apksigner verify my-app.apk
```

成功した場合、何も表示されないので注意が必要です。

以下のように `-v` か `--print-certs` をつけた方がわかりやすいかもしれません。

```console
$ apksigner verify -v app-debug.apk
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Number of signers: 1
```

```console
$ apksigner verify --print-certs app-debug.apk 
Signer #1 certificate DN: CN=Android Debug, O=Android, C=US
Signer #1 certificate SHA-256 digest: ca17bec5dd187fdb4a859b22f5db82b5251ab68b041df5b05dd885432771d5cd
Signer #1 certificate SHA-1 digest: 13199c0c7fdf8734d904925f5aa425c537cf8e69
Signer #1 certificate MD5 digest: ef94f75750de7d124796eb7c5ed38cf2
```

0 件のコメント: