秘密鍵で署名?公開鍵で暗号化?Androidアプリ署名の仕組みを完全理解する

Tags: #Security #Android #Cryptography #初心者向け

「公開鍵と秘密鍵、どっちで暗号化して、どっちで署名するんだっけ?」

公開鍵暗号方式を学んだ際、多くの人が一度はこの混乱に陥ります。

今回は、この「暗号化」と「電子署名」の決定的な違いから、実際にAndroidアプリ(APK)がどのように署名され、そしてユーザーのスマホでどう検証されているのかまでをスッキリ解説します。

1. 「暗号化」と「電子署名」は目的が真逆

結論から言うと、**「中身を隠したい」のか、「自分が作ったと証明したい」**のかによって、使う鍵が逆になります。

暗号化:中身を秘密にする(機密性)

特定の人にだけ読んでほしい場合です。

電子署名:本人であることを証明する(真正性・完全性)

「このデータは間違いなく自分が作った」と証明し、改ざんを防ぎたい場合です。

目的 やること 使う鍵 誰が実行する?
暗号化 内容を他人に見せない 相手の公開鍵 送り手(誰でもOK)
電子署名 本人が書いたと証明する 自分の秘密鍵 本人(秘密鍵の持ち主)

2. Androidアプリにおける「署名」の役割

Androidアプリをリリースする際、開発者は必ず自分の**秘密鍵(キーストア)**を使ってアプリ(APK/AAB)に署名を行います。これは具体的に以下の3つの役割を果たしています。

  1. 作者の証明(なりすまし防止):

    公開鍵で検証可能な署名があることで、「間違いなくこの開発者がビルドしたアプリである」と証明できます。

  2. 改ざんの検知(安全性の確保):

    ビルド後に第三者がマルウェアを仕込むなどして1ビットでも改ざんした場合、署名検証が失敗するため不正を検知できます。

  3. アップデートの同一性担保:

    Android OSは、既存アプリの更新時に「新旧のアプリが同じ秘密鍵で署名されているか」をチェックします。これにより、悪意のある別アプリでの上書き乗っ取りを防ぎます。

[!WARNING]

秘密鍵(Keystore)の紛失・流出は致命傷

秘密鍵をなくすと、二度とそのアプリのアップデートができなくなります(別アプリとして出し直すハメに)。流出すれば、悪意のある第三者が正規アップデートのふりをしてマルウェアをばら撒けてしまいます。

※最近はGoogle側で鍵を安全に管理してくれる「Play アプリ署名 (Play App Signing)」の利用が推奨されています。


3. 利用者側での「検証」はどう行われているのか?

「開発者が署名するのは分かったけど、利用者はどうやって検証するの?コマンドを打つ?」と思うかもしれません。

安心してください。利用者は何もしなくてOKです。Android OSがバックグラウンドで自動的に検証してくれます。

インストール時のOSの挙動

ユーザーが「インストール」を押した瞬間、OSは以下のステップをミリ秒単位で実行しています。

  1. APK内の証明書から公開鍵を取り出す。

  2. 公開鍵を使ってアプリの署名を復号し、開発者がビルドした時点の「ハッシュ値(指紋)」を取得する。

  3. 今まさにインストールしようとしているAPKデータから、改めて現在のハッシュ値を計算する。

  4. 2と3を比較する。

ここでハッシュ値が一致しなければ、OSは「パッケージが破損している」「署名が一致しない」としてインストールを強制ブロックします。ユーザーは知らぬ間にOSに守られているわけです。

(おまけ)手動で検証したい場合

野良アプリの検証など、CLIで手動確認したい場合はAndroid SDKの apksigner が使えます。

Bash

# APKの署名情報を確認するコマンド
$ apksigner verify --print-certs target_app.apk

まとめ