iOSアプリ証明書（Apple Developer）概要

# はじめに

こんにちは。エン・ジャパン株式会社でネイティブアプリエンジニアをしております谷田貝です。

弊社では公開しているiOSアプリが多くあり、その証明書類を扱う方も多くいます。[Apple Developer](https://developer.apple.com/)のiOSアプリ証明書類は複雑で理解するのも大変なため、社内で勉強会を行いました。本記事ではその内容を展開します。お役に立てれば幸いです。

###### 本記事の目的
- iOSアプリ開発にて扱う証明書類の相関関係、発行から使用までの流れを説明
- 各種証明書類の特徴や扱う上での留意事項の説明

###### 想定読者
- これからiOSアプリ開発を始める方、証明書周りを理解したい方
- 協力会社にiOSアプリ証明書類を提供する必要がある方

###### 記載対象
- 証明書類の発行手順詳細については割愛
- iOSアプリ作成、運用において主なもののみ説明


# iOSアプリ証明書 なぜ必要か、何に使うのか
主なものは・・・
- Development / Distribution Certificate
    - 証明書を発行した開発者によりアプリが作成されたこと、アプリが改ざんされていないことを証明
- Provisioning Profile
    - アプリのCertificate、App ID、使用可能な機能、デバイスリストを関連付け、インストールできる端末を定義
- Apple Push Service (APNs) Certificate
    - アプリへPush通知を送信する際、通知の送信元サービスからAPNsに接続する際の暗号化通信に使用


# 開発・配布証明書（発行 〜 アプリのビルド・実行）

![ios_figure_1_build.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3456096/085a4d41-990f-fc0f-878d-bc2261209a49.png)
↑UDIDはDevelopment、Ad Hoc配信時のみ使用します


まず、開発・配布証明書を発行してからアプリをビルドして実行するまでの流れです。図中①〜⑥の番号は下記の番号に対応しています。

### ① キーペアとCSRの作成
- 秘密鍵・公開鍵のペア（RSA公開鍵暗号方式）と、CSR（Certificate Signing Request）を作成
- CSRには、秘密鍵で暗号化した開発者署名と、公開鍵が含まれる

RSA公開鍵暗号方式については書籍「[暗号技術入門 第3版(結城 浩)](https://www.amazon.co.jp/dp/4797382228)」がおすすめです。
さくっと概要を知りたい場合は「[デジタル署名の仕組み](https://www.infraexpert.com/study/security5.html)」もわかりやすいです。

### ② CSRからCertificateの作成
- CSRをApple Developer上で読み込む
- 開発者署名が公開鍵で復号できることが検証されると、Apple側の署名が付与されてCertificate（証明書）となる
- Certificateはダウンロードしてキーチェーンアクセスに取り込んでおく 

### ③ App ID、UDID、Provisioning Profileの登録
- App ID（アプリの識別子）を登録
- UDID（端末識別子）を登録（DevelopmentでUSB接続 / Ad Hoc配信の場合のみ必要）
- Certificate、App ID、UDIDを紐づけてProfileを登録
- ProfileはXcodeから自動ダウンロードか手動読み込み

### ④ ipaファイルの作成
- Xcode上で、iOS ApplicationとProvisioning Profile、Certificateに対応する秘密鍵によりCode Signatureを付加

### ⑤ iOS上でアプリ実行
- MacからUSB接続、またはApp Store他経由でiOSにインストール
- iOS上にアプリがインストールされる際、改ざんされていないこと、Provisioning Profileの指定要件を満たしているか検証される

### ⑥ p12ファイルの書き出し
- CI/CD環境や複数の開発者のMacでビルドを行うためには、Certificateと秘密鍵を合わせたp12ファイルへ書き出し、他方で取り込む必要がある

担当者の離任時や、協力会社の契約変更時など、p12ファイルが無いとそれなりに困るので忘れず管理しておきましょう。


# Push通知証明書（発行 〜 Push通知設定・送信）

![ios_figure_2_apns.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3456096/0f431006-d926-22b6-a193-5b7e210b4986.png)
続いて、Push通知証明書の発行からPush通知の設定とPush通知を送信するまでの流れです。図中①〜⑥の番号は下記の番号に対応しています。

### ① キーペアとCSRの作成
- 秘密鍵・公開鍵のペア（RSA公開暗号方式）と、CSR（Certificate Signing Request）を作成
- CSRには、秘密鍵で暗号化した開発者署名と公開鍵が含まれる

※開発・配布証明書と同様です

### ② CSRからCertificateの作成
- CSRをApple Developer上で読み込む
- 開発者署名が公開鍵で復号できることが検証されると、Apple側の署名が付与されてCertificate（証明書）となる
- Certificateはダウンロードしてキーチェーンアクセスに取り込んでおく
- **App IDと関連付け**て生成される

※開発・配布証明書とほぼ同じですが、App IDと関連付ける点が異なります

### ③ p12ファイルの書き出し
- Push通知サービス側への設定のため、Certificateと秘密鍵を合わせたp12ファイルを書き出す

### ④ p12ファイルを通知サービスに設定
- 通知サービスの仕様に従ってp12ファイルを設定
Firebase: [Apple プラットフォームで Firebase Cloud Messaging クライアント アプリを設定する](https://firebase.google.com/docs/cloud-messaging/ios/client?hl=ja)
Repro: [APNs証明書の設定 (iOS) — Repro ドキュメント](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.html#p12repro)

### ⑤ 通知許諾とトークン連携
- アプリ起動後、通知許諾するとAPNs側で端末登録され、デバイストークンが発行される
- 発行されたデバイストークンを通知サービスへ連携する

### ⑥ 通知サービス・APNs間の通信暗号化
- 通知サービスにて送信トリガーが発生した際、通知サービスとAPNs間でp12ファイルの内容を基に通信が暗号化され、デバイストークンと通知データが安全に届けられる

# 各種証明書類の特徴・注意点


### Certificate について

##### Certificate の分類と特徴
- Development Certificate
    - MacからUSB接続で実機端末の動作確認用
    - iOS / Mac用があり、まとめた後継が (Apple) Development
    - ユーザアカウント単位で作成可能

- Distribution Certificate
    - Ad Hoc配信やApp Store (TestFlight / リリース) 配信用
    - iOS / Mac用があり、まとめた後継が (Apple) Distribution
    - 各種別**3つまでしか作成できない**

- Apple Push Notification service SSL Certificate
    - Push通知送信サービス用
    - Sandbox (開発用) / Production (製品用) がある
    - 1つのApp IDにつき各種別**2つ作成可能**

##### Certificate の有効期限切れへの対応
- Development / Distribution Certificate
    - 有効期限は発行から1年（expired表示もなく消える）
    - アプリの更新時に必要、配信中アプリには影響なし
    - キーペア、CSR、Certificate、Provisioning Profileを再作成

- Apple Push Notification service SSL Certificate
    - 有効期限は発行から1年（expired表示もなく消える）
    - Push通知送信時に必要、**期限切れでPush通知利用不可**
    - 1つのApp IDにつき各種別**2つ作成可能**なため、1つ目の (a) の期限切れ前に期限の長いもう1つ (b) を作成しておき、通知サービス側のp12ファイルを (a) → (b) と切り替えて対応
    - p12 Certificate ではなく p8 key を使用する手法もある
        - p8 key は有効期限無し
        - p8 key はApp ID単位での管理や環境の区別はできない
        - p8 key の発行可能数はADP契約につき2つまで


### App ID について

##### App ID の特徴
- アプリを特定する識別子 (Team ID + Bundle ID)
- 有効期限は無し
- アプリで有効にする機能を選択可能（Push通知等）
- アプリで有効にする機能を後から編集した場合、Provisioning Profile の再作成が必要
- 一度登録した Bundle ID は変更不可
- 一度登録した Bundle ID は削除後も再作成不可
- App Extension (拡張機能) を使用する場合はアプリ本体の他にもID定義が必要
    例) com.example.myappid.**extension**


### Device について

##### Device の特徴
- 実機端末を特定する識別子（UDID）を登録
- DevelopmentでMacからUSB接続での実機確認や、Ad Hoc配信での実機確認に使用
- Provisioning Profile 作成時に選択して紐付ける
- iOS, iPadなど、デバイスタイプ毎に**100台が登録上限**
- 1度登録すると、**年に1度の契約更新時しか削除できない**（無効化は随時実行可能）
- 無効化すると、紐付けられた Provisioning Profile は再作成が必要（Device Nameの変更は影響無し）
- 会社や所属、所有者がわかる Device Name を推奨（端末の所有者と連絡を取れる状態に）

### Provisioning Profile について

##### Provisioning Profile の分類と特徴
- Development (iOS App Development)
    - MacからUSB接続で特定実機端末の動作確認に使用
    - App ID、Certificate を選択 (Development)
    - 利用可能とする Device を選択

- Distribution (Ad Hoc)
    - 私設サーバ等から特定実機端末へのアプリ配信に使用
    - App ID、 Certificate を選択 (Distribution)
    - 利用可能とする Device を選択

- Distribution (App Store)
    - TestFlight、製品リリースに使用
    - App ID、 Certificate を選択 (Distribution)
    - Device は選択不要
        - TestFlight内部テスト: Apple Developer のユーザ単位で利用
        - TestFlight外部テスト: Eメールで招待して利用

##### Provisioning Profile の有効期限切れ / 失効への対応
- Certificate の期限切れ
    - 新たに作成した Certificate に変更して再作成

- App ID の有効機能の変更による失効
    - 同じ App ID を選択して再作成

- 関連付けた Device の無効化による失効
    - 有効な Device を再選択して再作成


# おわりに
Apple Developerは [公式ドキュメント](https://developer.apple.com/jp/help/account/) に仕様の詳細までは記載されていないこともあるため、実際に動かして確認してみるのが理解への早道かと思います。個人契約して色々試してみるのもおすすめです。