Summary
この文章は、iOSの認証流れ、Provisioning Profile、entitlements、CertificateSigningRequest、p12、AppIDなどの概念の整理、企業内Appleのアプリ開発する時のローカルビルド必要なものと、なぜそのものを必要かのかをまとめます。
なぜかAppleの認証が複雑ですか?
AndroidとWindowsアプリに比べると、Appleアプリだけ色々複雑な認証手順があります。その原因はAppleが第三者からのアプリ発行、野良アプリを禁止させたいことです。
iOSデバイスにインストールされたアプリを全てAppleから認証をもらったものと言うルールを徹底的実行しています。
0. 暗号化方法紹介
まず、RSA暗号技術についてこちらの文章を読んでください。RSAの公開鍵と秘密鍵が署名な時使われてます。
公開鍵暗号(非対称鍵暗号)の仕組みをわかりやすく解説してみる
1. 一番シンプルな流れ
アプリに署名と認証の一番シンプルな流れと考えたら、Apple側公開鍵と秘密鍵のペアを生成し、iOSデバイスに公開鍵を置きまして、Appleのサーバー内部に秘密鍵を置きます。
Apple Storeにアプリをアップロードするとき秘密鍵でアプリを署名し、iOSデバイスでAppをダウンロードした後公開鍵でアプリを認証します。
これで、全てのAppをApple側から許可されたことを確保できます。
ただし、アプリ開発する時に、実機で検証することが必要なので、直接にXcodeからインストールの場面が発生する。また、企業内部のテストや、内部検証の必要にもあるので、この時はどうしますか?
2. 実機に直接インストール
開発するときApple Store経由しなく、直接にデバイスにインストールする時下記の二つことを確保しないといけない:
- アプリはAppleから認証されたことを確保
- 他のApp(非今回開発用のApp)をインストールできないことを確保(全てローカルビルドしたアプリを直接にインストールできないようにする。いわゆる野良アプリのインストールは禁止)
i. Appleから認証されたことを確保
下記の流れて、Apple側が二重署名して、問題を解決できます。
- 開発用のデバイス(Mac)からキーペアを生成します:公開鍵L と 秘密鍵L(L for Local)
- Appleから生成した鍵ペアがあります。前述のAppleStoreの例と同じ、秘密鍵はApple側所持していて、公開鍵は各iOSデバイスにいます:公開鍵A,秘密鍵A。A for Apple
- Macから生成した公開鍵LをAppleに提供して、Appleは秘密鍵Aを使って公開鍵Lをサインする。そして、公開鍵Lとそのサインしたデータを取得し、証明書と呼べます。
- アプリをビルドした後、Mac内の秘密鍵をアプリに署名して、そのステップ3でもらった証明書と一緒にアプリにパックして、デバイスにインストールする。
- インストールする時、iOSデバイスを内部の公開鍵Aをサインを正しいかどうかを検証する(Appleに登録されたMacでビルドしたものかどうか)
- 公開鍵AはAppleで認証されたことを確認し、公開鍵Lをアプリの署名を検証する。
上記の流れて、AppをAppleに許可したものかどうかを判断する。
ii. 他のAppをインストールできないことを確保
iの流れでは、Appleに許可されたアプリかどうかを検証しましたが、野良アプリを乱用する問題がまだ解決してない。
この問題を解決するため、Apple側下記の手法があります:
- インストールしたいデバイスをAppleに登録すること。(開発端末登録)
- 署名は特定のアプリにします。(Bundle ID)
2を実現する手法は上記の流れのステップ3でいろんな情報を追加することができるので、そこでデバイスIDとアプリID(Bundle ID:com.company.xxx)も一緒に証明書を作成、署名することになります。
iii. 最終の流れ
証明書のフォーマットがあるので、不要な情報(Bundle IDなど)が入るのをあまり良くないため、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を合ってるかどうかを検証することができます。
iv. 具体的な操作
具体的な操作は簡単にまとめます:
- ステップ1はMacのkeychainからの認証局に証明書を要求から生成する。生成したCertificateSigningRequestは公開鍵Lです
- ステップ2はAppleの仕組み
- ステップ3ではCertificateSigningRequestをAppleにアップロードし、Apple側の秘密鍵Aで署名した後の署名書をダウンロードする。現在二つの証明書が存在します。一つはKeychainからローカルで生成したもの、もう一つは、Apple署名したものです。keychainはこの二つの証明書は関連します。Xcodeをビルドするとき、KeychainからApple署名した証明書対応の秘密鍵Lを探し、その秘密鍵Lを使って、Appを署名します。当然、ローカル生成した秘密鍵はこの開発端末しか持ってないので、他のMacを利用したい時は秘密鍵を書き出すことが必要です。ここで.p12ファイルを出てきます。秘密鍵を書き出したp12ファイルを他のMacにインストールした後、同じ鍵を持ちまして、アプリの開発とビルドができます。
- ステップ4にもApple側で操作します。最後生成した Provisioning Profileファイルをダウンロードする。
- ステップ5でXCodeはKeychainからステップ3の証明書を対応した秘密鍵Lを探し、アプリを署名します。Xcodeで対応のAppIDとProvisioning Profile 設定することが必要です。(ここはなぜかProvisioning Profile•AppID・デバイスID(登録されてないデバイス)を間違ってるとビルドやインストール失敗することがわかります)
他はXcodeとiOSシステム自動でやること。詳細な手順をここに参考してください。https://dev.classmethod.jp/articles/ios-certificates/
3. 概念のまとめ
- 証明書(cer):Macで生成した公開鍵と秘密鍵,Apple側生成した公開鍵に署名した後のデータファイル。
- Entitlements:アプリ権限(プッシュ通知など)のファイル
- CertificateSigningRequest:ローカル生成した公開鍵。
- p12:ローカルの秘密鍵書き出したもの
- Provisioning Profile:証明書 / Entitlements/デバイスIDなどのデータを含め,Apple側の秘密鍵で署名したデータファイル。
文章评论
全日文技术文章!nb!
纯日文技术文章,nb!