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経由しなく、直接にデバイスにインストールする時下記の二つことを確保しないといけない:
- AppはAppleから認証されたことを確保
- 他のApp(非今回開発用のApp)をインストールできないことを確保(全てローカルビルドしたアプリを直接にインストールできないようにする。いわゆる野良アプリを禁止)
Appleから認証されたことを確保
Apple側が二重署名をしています。

- 開発用のMacからキーペアを生成します:公開鍵L と 秘密鍵L(L for Local)
- Appleから生成した鍵ペアがあります。前述のAppleStoreの例と同じ、秘密鍵はApple側所持していて、公開鍵は各iOSデバイスにいます:公開鍵A,秘密鍵A。A for Apple
- Macから生成した公開鍵LをAppleに提供して、Appleは秘密鍵Aを使って公開鍵Lをサインする。そして、公開鍵Lとそのサインしたデータを取得し、証明書と呼べます。
- 開発するときに、Appビルドした後、Mac内の秘密鍵をAppにサインして、そのステップ3でもらった証明書と一緒にAppにパックして、デバイスにインストールする。
- インストールする時、iOSデバイスを内部の公開鍵Aをサインを正しいかどうかを検証する(Appleに登録されたMacでビルドしたものかどうか)
- 公開鍵LはAppleで認証されたことを確認し、公開鍵Lをアプリのサインを検証する。
上記の流れて、AppをAppleに許可したものかどうかを判断する。
他のAppをインストールできないことを確保
先のサインの流れは、Appleに許可されたAppかどうかを検証しましたが、アプリを乱用できない問題が解決してない。
この問題を解決するため、Apple側下記の手法があります:
- インストールしたいデバイスをAppleに登録すること。(開発端末登録)
- 署名は特定のアプリにします。(Bundle ID)
2を実現する手法は上記の流れのステップ3でいろんな情報を追加することができるので、そこでデバイスIDとアプリID(Bundle ID:com.company.xxx)も一緒に証明書を作成、署名することになります。

最終の流れ
証明書基本なフォーマットがあるので、はいろんなことが入るのをあまり良くないため、Apple側にProvisioning Profileというものを提出しました。
Provisioning Profileのファイルの中に上記のデバイスID、App ID以外にはプッシュ通知・iCloudなどの権限管理のEntitlementsファイルを含めます。
最終的の流れが複雑になりました:

- 開発用のMacからキーペアを生成します:公開鍵L と 秘密鍵L(L for Local)
- Appleから生成した鍵ペアがあります。前述のAppleStoreの例と同じ、秘密けんはApple側所持していて、公開鍵は各iOSデバイスにいます:公開鍵A,秘密鍵A。A for Apple
- Macから生成した公開鍵LをAppleに提供して、Appleは秘密鍵Aを使って公開鍵Lをサインする。そして、公開鍵Lとそのサインしたデータを取得し、証明書(cer)と呼べます。
- Apple Developer ProgramからAppIDを申請、開発端末を登録、アプリ使用する機能の権限(Push通知など)を設定し、ステップ3でもらった証明書データと一緒に秘密鍵Aを署名して、Provisioning Profileを作成、ローカルの開発Macにダウンロードする。
- 開発するときに、Appビルドした後、Mac内の秘密鍵をAppにサインして、そのステップ4でもらったProvisioning Profileと一緒にAppにパックして(embedded.mobileprovision)、デバイスにインストールする。
- インストールする時、iOSデバイスを内部の公開鍵Aをembedded.mobileprovision の中のサインは正しいかどうかを検証する
- 公開鍵LはAppleで認証されたことを確認し、公開鍵Lをアプリの署名を検証する。
- 検証を終わったらデバイスID、AppIDまたか各権限のファイルEntitlementsを合ってるかどうかを検証することができます。
具体的な操作
具体的な操作は簡単にまとめます:
- ステップ1はMacのkeychainからの認証局に証明書を要求から生成する。生成したCertificateSigningRequestは公開鍵Lです
- ステップ2はAppleの仕組み
- ステップ3ではCertificateSigningRequestをAppleにアップロードし、Apple側の秘密鍵Aで署名した後の署名書をダウンロードする。現在二つの証明書が存在します。一つはKeychainからローカルで生成したもの、もう一つは、署名したもの。keychainはこの二つの証明書は関連します。Xcodeをビルドするとき、KeychainからApple署名した証明書対応の秘密鍵Lを探し、その秘密鍵Lを使って、Appを署名します。当然、ローカル生成した秘密鍵はこの開発端末しか持ってないので、他のMacを利用したい時は秘密鍵を書き出すことが必要です。ここで.p12ファイルを出てきます。秘密鍵を書き出したp12ファイルを他のMacにインストールした後、同じ鍵を持ちまして、アプリの開発とビルドができます。
- ステップ4にもApple側で操作します。最後生成した Provisioning Profileファイルをダウンロードする。
- ステップ5XCode はKeychainからステップ3の証明書を対応した秘密鍵Lを探し、Appを署名します。Xcodeで対応のAppIDとProvisioning Profile 設定することが必要です。(ここはなぜかProvisioning Profile•AppID・デバイスID(登録されてないデバイス)を間違ってるとビルドやインストール失敗することがわかります)
他はXcodeとiOSシステム自動でやること。詳細な手順をここに参考してください。https://dev.classmethod.jp/articles/ios-certificates/
概念のまとめ
- 証明書(cer):Macで生成した公開鍵と秘密鍵,Apple側生成した公開鍵に署名した後のデータファイル。
- Entitlements:アプリ権限(プッシュ通知など)のファイル
- CertificateSigningRequest:ローカル生成した公開鍵。
- p12:ローカルの秘密鍵書き出したもの
- Provisioning Profile:証明書 / Entitlements/デバイスIDなどのデータを含め,Apple側の秘密鍵で署名したデータファイル。
全日文技术文章!nb!
纯日文技术文章,nb!