Apple Storeにアプリ認証について

Summary

この文章は、iOSの認証流れ、Provisioning Profile、entitlements、CertificateSigningRequest、p12、AppIDなどの概念の整理、現在Noaでローカルビルド必要なものと、なぜそのものを必要かのをまとめます。

なぜかAppleの認証が複雑ですか?

AndroidとWindowsアプリに比べると、iOSだけ色々複雑な認証が必要です。その原因はAppleは第三者のアプリの発行、野良アプリを禁止したいことです。
すべでのiOSデバイスにインストールしたものを絶対Appleから認証をもらったこと徹底的実行しています。

暗号化方法紹介

Appleの認証技術は当然RSA暗号技術を利用します。
公開鍵暗号(非対称鍵暗号)の仕組みをわかりやすく解説してみる

一番簡単な流れ

一番簡単な流れはApple側公開鍵と秘密鍵のペアを生成し、iOSデバイスに公開鍵を置きまして、Appleのサーバー内部に秘密鍵を置きます。
Apple StoreにAppをアップロードするとき秘密鍵でアプリを署名し、iOSデバイスでAppをダウンロードした後公開鍵でアプリを認証します。
これで、全てのAppをApple側から許可されたことを確保できます。

ただ、開発するときに、実機で検証することが必要なので、直接にXcodeからインストールの場面が発生する。また、企業内部のテストや、内部検証の場面にも発生します。
この時はどうしますか?

実機に直接インストール

開発するときApple Store経由しなく、直接にデバイスにインストールする時下記の二つことを確保しないといけない:

  1. AppはAppleから認証されたことを確保
  2. 他のApp(非今回開発用のApp)をインストールできないことを確保(全てローカルビルドしたアプリを直接にインストールできないようにする。いわゆる野良アプリを禁止)

Appleから認証されたことを確保

Apple側が二重署名をしています。

  1. 開発用のMacからキーペアを生成します:公開鍵L と 秘密鍵LL for Local)
  2. Appleから生成した鍵ペアがあります。前述のAppleStoreの例と同じ、秘密鍵はApple側所持していて、公開鍵は各iOSデバイスにいます:公開鍵A秘密鍵AA for Apple
  3. Macから生成した公開鍵LをAppleに提供して、Appleは秘密鍵Aを使って公開鍵Lをサインする。そして、公開鍵Lとそのサインしたデータを取得し、証明書と呼べます。
  4. 開発するときに、Appビルドした後、Mac内の秘密鍵をAppにサインして、そのステップ3でもらった証明書と一緒にAppにパックして、デバイスにインストールする。
  5. インストールする時、iOSデバイスを内部の公開鍵Aをサインを正しいかどうかを検証する(Appleに登録されたMacでビルドしたものかどうか)
  6. 公開鍵LはAppleで認証されたことを確認し、公開鍵Lをアプリのサインを検証する。

上記の流れて、AppをAppleに許可したものかどうかを判断する。

他のAppをインストールできないことを確保

先のサインの流れは、Appleに許可されたAppかどうかを検証しましたが、アプリを乱用できない問題が解決してない。
この問題を解決するため、Apple側下記の手法があります:

  1. インストールしたいデバイスをAppleに登録すること。(開発端末登録)
  2. 署名は特定のアプリにします。(Bundle ID)

2を実現する手法は上記の流れのステップ3でいろんな情報を追加することができるので、そこでデバイスIDとアプリID(Bundle ID:com.company.xxx)も一緒に証明書を作成、署名することになります。

最終の流れ

証明書基本なフォーマットがあるので、はいろんなことが入るのをあまり良くないため、Apple側にProvisioning Profileというものを提出しました。

Provisioning Profileのファイルの中に上記のデバイスID、App ID以外にはプッシュ通知・iCloudなどの権限管理のEntitlementsファイルを含めます。

最終的の流れが複雑になりました:

  1. 開発用のMacからキーペアを生成します:公開鍵L と 秘密鍵LL for Local)
  2. Appleから生成した鍵ペアがあります。前述のAppleStoreの例と同じ、秘密けんはApple側所持していて、公開鍵は各iOSデバイスにいます:公開鍵A秘密鍵AA for Apple
  3. Macから生成した公開鍵LをAppleに提供して、Appleは秘密鍵Aを使って公開鍵Lをサインする。そして、公開鍵Lとそのサインしたデータを取得し、証明書(cer)と呼べます。
  4. Apple Developer ProgramからAppIDを申請、開発端末を登録、アプリ使用する機能の権限(Push通知など)を設定し、ステップ3でもらった証明書データと一緒に秘密鍵Aを署名して、Provisioning Profileを作成、ローカルの開発Macにダウンロードする。
  5. 開発するときに、Appビルドした後、Mac内の秘密鍵をAppにサインして、そのステップ4でもらったProvisioning Profileと一緒にAppにパックして(embedded.mobileprovision)、デバイスにインストールする。
  6. インストールする時、iOSデバイスを内部の公開鍵Aをembedded.mobileprovision の中のサインは正しいかどうかを検証する
  7. 公開鍵LはAppleで認証されたことを確認し、公開鍵Lをアプリの署名を検証する。
  8. 検証を終わったらデバイスID、AppIDまたか各権限のファイルEntitlementsを合ってるかどうかを検証することができます。

具体的な操作

具体的な操作は簡単にまとめます:

  1. ステップ1はMacのkeychainからの認証局に証明書を要求から生成する。生成したCertificateSigningRequestは公開鍵Lです
  2. ステップ2はAppleの仕組み
  3. ステップ3ではCertificateSigningRequestをAppleにアップロードし、Apple側の秘密鍵Aで署名した後の署名書をダウンロードする。現在二つの証明書が存在します。一つはKeychainからローカルで生成したもの、もう一つは、署名したもの。keychainはこの二つの証明書は関連します。Xcodeをビルドするとき、KeychainからApple署名した証明書対応の秘密鍵Lを探し、その秘密鍵Lを使って、Appを署名します。当然、ローカル生成した秘密鍵はこの開発端末しか持ってないので、他のMacを利用したい時は秘密鍵を書き出すことが必要です。ここで.p12ファイルを出てきます。秘密鍵を書き出したp12ファイルを他のMacにインストールした後、同じ鍵を持ちまして、アプリの開発とビルドができます。
  4. ステップ4にもApple側で操作します。最後生成した Provisioning Profileファイルをダウンロードする。
  5. ステップ5XCode はKeychainからステップ3の証明書を対応した秘密鍵Lを探し、Appを署名します。Xcodeで対応のAppIDとProvisioning Profile 設定することが必要です。(ここはなぜかProvisioning Profile•AppID・デバイスID(登録されてないデバイス)を間違ってるとビルドやインストール失敗することがわかります)

他はXcodeとiOSシステム自動でやること。詳細な手順をここに参考してください。https://dev.classmethod.jp/articles/ios-certificates/

概念のまとめ

  1. 証明書(cer):Macで生成した公開鍵と秘密鍵,Apple側生成した公開鍵に署名した後のデータファイル。
  2. Entitlements:アプリ権限(プッシュ通知など)のファイル
  3. CertificateSigningRequest:ローカル生成した公開鍵。
  4. p12:ローカルの秘密鍵書き出したもの
  5. Provisioning Profile:証明書 / Entitlements/デバイスIDなどのデータを含め,Apple側の秘密鍵で署名したデータファイル。

Reference

iOS App 签名的原理(Written in Chinese)

Comments

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注