Tags: #Security #Android #Cryptography #初心者向け
「公開鍵と秘密鍵、どっちで暗号化して、どっちで署名するんだっけ?」
公開鍵暗号方式を学んだ際、多くの人が一度はこの混乱に陥ります。
今回は、この「暗号化」と「電子署名」の決定的な違いから、実際にAndroidアプリ(APK)がどのように署名され、そしてユーザーのスマホでどう検証されているのかまでをスッキリ解説します。
結論から言うと、**「中身を隠したい」のか、「自分が作ったと証明したい」**のかによって、使う鍵が逆になります。
特定の人にだけ読んでほしい場合です。
アクション: 相手の公開鍵でロックをかける。
結果: ロックした本人すら開けられず、対応する秘密鍵を持つ相手(受信者)だけが復号して読める。
イメージ: 誰でも手紙を入れられるが、鍵を持つ管理人しか開けられない「郵便ポスト」。
「このデータは間違いなく自分が作った」と証明し、改ざんを防ぎたい場合です。
アクション: 自分の秘密鍵でデータ(のハッシュ値)を暗号化する=署名。
結果: 誰でも公開鍵を使って検証できるが、その署名を作れるのは秘密鍵を持つ本人だけ。
イメージ: 誰でも印鑑証明で照合できるが、本人しか押せない「実印」。
| 目的 | やること | 使う鍵 | 誰が実行する? |
|---|---|---|---|
| 暗号化 | 内容を他人に見せない | 相手の公開鍵 | 送り手(誰でもOK) |
| 電子署名 | 本人が書いたと証明する | 自分の秘密鍵 | 本人(秘密鍵の持ち主) |
Androidアプリをリリースする際、開発者は必ず自分の**秘密鍵(キーストア)**を使ってアプリ(APK/AAB)に署名を行います。これは具体的に以下の3つの役割を果たしています。
作者の証明(なりすまし防止):
公開鍵で検証可能な署名があることで、「間違いなくこの開発者がビルドしたアプリである」と証明できます。
改ざんの検知(安全性の確保):
ビルド後に第三者がマルウェアを仕込むなどして1ビットでも改ざんした場合、署名検証が失敗するため不正を検知できます。
アップデートの同一性担保:
Android OSは、既存アプリの更新時に「新旧のアプリが同じ秘密鍵で署名されているか」をチェックします。これにより、悪意のある別アプリでの上書き乗っ取りを防ぎます。
[!WARNING]
秘密鍵(Keystore)の紛失・流出は致命傷
秘密鍵をなくすと、二度とそのアプリのアップデートができなくなります(別アプリとして出し直すハメに)。流出すれば、悪意のある第三者が正規アップデートのふりをしてマルウェアをばら撒けてしまいます。
※最近はGoogle側で鍵を安全に管理してくれる「Play アプリ署名 (Play App Signing)」の利用が推奨されています。
「開発者が署名するのは分かったけど、利用者はどうやって検証するの?コマンドを打つ?」と思うかもしれません。
安心してください。利用者は何もしなくてOKです。Android OSがバックグラウンドで自動的に検証してくれます。
ユーザーが「インストール」を押した瞬間、OSは以下のステップをミリ秒単位で実行しています。
APK内の証明書から公開鍵を取り出す。
公開鍵を使ってアプリの署名を復号し、開発者がビルドした時点の「ハッシュ値(指紋)」を取得する。
今まさにインストールしようとしているAPKデータから、改めて現在のハッシュ値を計算する。
2と3を比較する。
ここでハッシュ値が一致しなければ、OSは「パッケージが破損している」「署名が一致しない」としてインストールを強制ブロックします。ユーザーは知らぬ間にOSに守られているわけです。
野良アプリの検証など、CLIで手動確認したい場合はAndroid SDKの apksigner が使えます。
Bash
# APKの署名情報を確認するコマンド
$ apksigner verify --print-certs target_app.apk
公開鍵で暗号化 = 中身を隠す
秘密鍵で署名 = 本人証明と改ざん防止
Androidアプリは開発者の秘密鍵で署名され、インストール時にOSが自動で公開鍵を使って検証することで安全性を保っている。