IOSアプリでPUSH通知を実装する上での証明書のあれこれ

# Push通知を実装する上でのApple Developer証明書のあれこれ

Push通知を実装する上でのApple Developer証明書について、学んだ内容をまとめます。

---
## 目次
1. [CSR（Certificate Signing Request）とは？](#CSR-とは)
    - [CSRの概要](#CSRの概要)
    - [なぜCSRが必要なのか。](#なぜCSRが必要なのか。)
    - [公開鍵と秘密鍵の生成と管理](#公開鍵と秘密鍵の生成と管理)
2. [CSR提出と証明書発行の流れ](#CSR提出と証明書発行の流れ)
3. [証明書の種類と役割](#証明書の種類と役割)
    - [Software用の証明書](#Software用の証明書)
    - [Service用の証明書](#Service用の証明書)
4. [プロビジョニングプロファイルについて](#プロビジョニングプロファイルについて)
5. [プッシュ通知用の追加証明書（p8形式のAPNsキー）](#プッシュ通知用の追加証明書)
    - [APNsとp8キーの概要](#APNsとp8キーの概要)
    - [p8キーの作成方法](#p8キーの作成方法)
    - [Firebase Cloud Messagingでのp8キー設定](#Firebase-Cloud-Messagingでのp8キー設定)

---

## 1. CSR（Certificate Signing Request）とは？

### CSRの概要
**CSR（Certificate Signing Request）**は、新しい証明書を発行するために必要な情報を含んだファイルです。主に以下の情報が含まれます：

- **公開鍵（Public Key）**: 暗号通信の基盤となる鍵。秘密鍵と対をなします。(ここでは具体的な暗号化方式についての説明は省く)
- **開発者署名**: 開発者の身元を確認するためのデジタル署名。

![CSRファイルの説明イラスト](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/af7c9d4a-08de-7a26-6d53-b66c192acc5c.png)

このCSRファイルはApple Developerに自動（Xcode上で作成した場合）または手動（キーチェーンから作成した場合）で登録され、Appleがそれを基に証明書（CERファイル）を発行します。CSRファイル自体には自体には秘密鍵は含まれておらず、公開鍵のみが含まれるため、安全に取り扱うことができます。

### なぜCSRが必要なのか。
CSRは、証明書のセキュリティと信頼性を確保するために使用される。主な役割として以下の点が挙げられます：

- **認証の基盤**: 公開鍵と秘密鍵のペアを用いて、証明書の信頼性をローカル環境で検証します。また、同時にアプリが改竄されていないこと、証明書を発行した開発者によりアプリが開発されたことを保証します。
- **セキュリティの確保**: 秘密鍵は生成後、外部に漏れることなく安全に保管されます。

参考
[iOSアプリ証明書（Apple Developer）概要](https://qiita.com/enjapan_common_user/items/7fb6ec3a4dd5fa7e7b82)
[CSR(証明書署名要求)とは？ わかりやすく10分で解説](https://www.netattest.com/csr-2023_mkt_tst)

### 公開鍵と秘密鍵の生成と管理

1. **鍵ペアの生成**  
    CSR生成時に公開鍵（Public Key）と秘密鍵（Private Key）のペアが作成されます。  
    - **秘密鍵の生成**: 開発者がローカル環境（例：Mac）でCSRを生成する際に、秘密鍵を生成します。秘密鍵はローカルに安全に保管され、外部に漏れないように管理されます。
        - **macOSの場合**: 秘密鍵は「キーチェーンアクセス」に保存されます。
    - **公開鍵の生成**: 秘密鍵に対応する公開鍵をしたら、これがCSRに含まれます。公開鍵は証明書としてAppleに登録され、Appleはこの公開鍵を使用して証明書を署名します。

2. **鍵ペアの保存場所**  
    - **秘密鍵（Private Key）**:
        - **macOSのキーチェーンアクセス**: 秘密鍵はキーチェーン内に安全に保存され、システムによって管理されます。ユーザーは通常、秘密鍵に直接アクセスする必要はありません。
    - **公開鍵（Public Key）**:
        - 公開鍵はCSRに含まれ、Apple Developerに登録されます。公開鍵自体は秘密鍵と異なり、外部に公開しても安全ですが、証明書の信頼性を担保するために正確に管理されます。


---

## 2. CSR提出と証明書発行の流れ

### CSRの提出

#### キーチェーンアクセスからCSRを生成する場合:
macOSの「キーチェーンアクセス」を使用してCSRを生成した場合、生成されたCSRファイル（例：push_notification.csr）を手動でApple Developerアカウントにアップロードする必要があります。
- ![スクリーンショット 2024-11-05 21.38.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/884a04a4-0724-62ce-fcbb-2b5897b5f8db.png)
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/048028ae-be88-3ff7-d8e7-fa0a680d90e1.png)
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/956ba82c-43a3-e709-33b2-4ca1abb0ff81.png)

Apple Developerサイトにログインし、「Certificates, Identifiers & Profiles」セクションから新しい証明書を作成する際に、このCSRファイルをアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/511148fa-849f-c1fa-dd71-d9278c10ea74.png)
![スクリーンショット 2024-11-06 12.41.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/e9c02198-1661-0ed9-b2d9-ca6b2b21fb90.png)


#### Xcodeを使用する場合:
Xcodeの「Accounts」セクションから証明書を生成すると、Xcodeが自動的にCSRを作成し、Appleに送信します。この方法では、開発者が手動でCSRをアップロードする必要はありません。

- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/2b0981c3-bead-ba06-50b2-548896f14e4c.png)
- ![スクリーンショット 2024-11-06 12.19.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/9e8546d5-784e-9702-a4d1-ea314f81ae65.png)
- ![スクリーンショット 2024-11-06 12.26.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/c663aa81-462c-206d-ed5f-691836c2f866.png)

ここまでの流れを図解するといかのようになります。
![流れ図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/472a5000-06bf-5dc1-99e2-7e7e4855e772.png)

---

## 3. 証明書の種類と役割

Apple Developer Programでは、アプリケーションやサービスを安全に開発・配布するために、さまざまな証明書を発行する必要があります。これらの証明書は、全セクションにて開設したCSR（Certificate Signing Request）を用いてAppleに発行申請を行い、Appleがそれに基づいて発行します。ここでは、特にSoftware用とService用に分類される証明書について、それぞれの役割や作成方法、使用方法を解説します。

### Software用の証明書
ソフトウェア向けの証明書は、iOSやmacOSアプリなどのソフトウェアの開発・配布に関連したもので、アプリの信頼性を保証し、デバイス上で安全に実行できるようにする役割を持っています。以下は代表的なSoftware用の証明書です。

⚠︎以下の各説明書についてはchat gptによる情報で裏付けを確認していません。

#### 1. iOS App Development証明書
- **用途**: iOSデバイス上で開発中のアプリをテストするための証明書です。開発中のアプリをデバイスに直接インストールして動作確認を行う際に必要です。
- **作成方法**: 「Certificates, Identifiers & Profiles > Certificates」から「iOS App Development」を選択して作成します。
- **使用方法**: Xcodeと連携し、デバイスにアプリを直接デプロイしてテストします。この証明書を使用することで、Appleが開発者とアプリの関係を確認し、テスト用アプリとしての信頼性を認証します。
- **有効期限**: 通常1年間。期限が切れると、再度CSRを生成して新しい証明書を取得する必要があります。

#### 2. 配布用証明書（Distribution Certificate）
- **用途**: App Storeに公開するアプリや、企業内で配布する社内専用アプリを配布するための証明書です。
- **作成方法**: 「Certificates, Identifiers & Profiles > Certificates」から「App Store and Ad Hoc」または「In-House and Ad Hoc」を選択して作成します。
    - **App Store配布用**: App Storeにリリースする際に使用。
    - **社内配布用**: Apple Developer Enterprise Programに加入している企業が社内で専用アプリを配布するために使用。
- **有効期限**: 通常1年間。期限切れになると再びCSRを作成して新しい証明書を取得する必要があります。

#### 3. macOS、tvOS、watchOS向けの証明書
- **用途**: iOSアプリと同様に、macOS、tvOS、watchOSのプラットフォーム上でアプリを開発・配布する際に使用します。
- **作成方法**: 各プラットフォームに応じた証明書を、Apple DeveloperサイトのCertificatesセクションから選択して作成します。
- **有効期限**: 通常1年間。期限が切れる前に再発行が必要です。

### Service用の証明書
サービス用の証明書は、Appleの各種サービス（APNs、DeviceCheck、Apple Payなど）を利用する際に必要なもので、サーバーとAppleのサービス間での認証と安全な通信を確立します。以下は代表的なService用の証明書です。

#### 1. Apple Push Services証明書（APNs証明書）
- **用途**: Apple Push Notification Service（APNs）を通じて、アプリにプッシュ通知を配信するために使用される証明書です。
- **作成方法**: 「Certificates, Identifiers & Profiles > Certificates」から「Apple Push Notification service SSL (Sandbox & Production)」を選択し、CSRをアップロードして作成します。
- **使用方法**: プッシュ通知のリクエストをサーバーからAPNsに送信する際、この証明書を使用して認証を行います。開発環境用と本番環境用があり、環境ごとに適切な証明書を使用します。
- **有効期限**: 通常1年間。期限切れ前に更新が必要です。

#### 2. DeviceCheckサービス証明書
- **用途**: DeviceCheck APIを利用し、不正防止やデバイスの利用制限を管理するために必要な証明書です。
- **作成方法**: 「Certificates, Identifiers & Profiles > Certificates」でDeviceCheckに対応した証明書を選択し、CSRを提出して作成します。
- **使用方法**: 不正行為の検出やデバイスの制限設定を行う際に、DeviceCheckサービスとの認証にこの証明書を使用します。
- **有効期限**: 通常1年間。期限切れ前に更新が必要です。

#### 3. Apple Pay用証明書
- **用途**: Apple Payを使用した支払い処理を行う際に、サーバーとApple間の安全な通信を確立するための証明書です。
- **作成方法**: 「Certificates, Identifiers & Profiles > Certificates」でApple Payの証明書を選択して作成します。
- **使用方法**: Apple Payを通じて支払い処理を行う際、サーバーとApple間での取引の信頼性とセキュリティを確保します。
- **有効期限**: 通常1年間。期限が切れる前に更新が必要です。

### 各証明書の管理
Apple Developerの「Certificates, Identifiers & Profiles」で各証明書を管理し、発行後にキーチェーンに追加して使用することで、期限が切れる前に再発行手続きを行い継続的に利用できます。

ここまでを図解すると以下のようになります。
![証明書の管理画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/e9fcded0-44b2-c2f8-c3a4-2eba96efceed.png)

---

## 4. プロビジョニングプロファイルについて

### プロビジョニングプロファイルの役割
プロビジョニングプロファイルには以下の情報が含まれています：

- **証明書**: 前セクションで作成した証明書が含まれ、Appleがアプリの信頼性を保証します。
- **App ID（アプリケーションID）**: アプリを特定する識別情報で、アプリケーションの一意のIDです。
- **デバイスID（UDID）**: テストや社内配布を行うデバイスのリストが含まれ、指定されたデバイスのみでアプリを実行できます（シミュレーターは除く）。
- **権限（Entitlements）**: プッシュ通知やApp内課金などのアプリで利用する機能が定義されています。

プロビジョニングプロファイルがなければ、デバイスでアプリを実行できず、配布やテストが制限されてしまいます。

### プロビジョニングプロファイルの種類
プロビジョニングプロファイルは、用途に応じて以下の4種類に分かれます。

#### 1. 開発用プロビジョニングプロファイル（Development Provisioning Profile）
- **用途**: 開発者がiOSデバイス上でアプリをテストするために使用されます。通常、Xcodeを使用して直接デバイスにアプリをインストールする場合に必要です。
- **特徴**:
    - デバイスID（UDID）を登録することで、特定のデバイス上でのみテストが可能です。
    - 使用できる証明書は「iOS App Development」証明書など（これを包含する種類の証明書であれば同様に使用可能）です。
- **使用シナリオ**: Xcodeと接続したiPhoneやiPadでアプリのデバッグやテストを行う際に利用されます。

#### 2. Ad Hoc配布用プロビジョニングプロファイル（Ad Hoc Provisioning Profile）
- **用途**: テストチームやクライアントなど、開発者以外のユーザーにもアプリを配布してテストする際に使用されます。
- **特徴**:
    - 特定のデバイスのUDIDが必要で、登録されたデバイスでのみ動作します。
    - 使用できる証明書は「Distribution」証明書（Ad Hoc）等です。
- **使用シナリオ**: App Storeに公開する前に、社内や限られた範囲でのテスト用に配布する場合に利用されます。

#### 3. App Store配布用プロビジョニングプロファイル（App Store Provisioning Profile）
- **用途**: App Storeで一般公開するアプリをビルドする際に必要なプロビジョニングプロファイルです。
- **特徴**:
    - 特定のデバイスのUDIDは不要で、全ユーザーがApp Storeからダウンロードして利用可能です。
    - 使用できる証明書は「Distribution」証明書（App Store）です。
- **使用シナリオ**: App Storeでアプリを公開する場合に利用され、一般ユーザーがインストール可能となります。

#### 4. Enterprise配布用プロビジョニングプロファイル（In-House Provisioning Profile）
- **用途**: Apple Developer Enterprise Programに加入している企業が、社内専用アプリを従業員に配布するために使用されます。
- **特徴**:
    - デバイスのUDID登録は不要で、企業内の従業員が無制限にインストールできます。
    - 使用できる証明書は「In-House Distribution」証明書です。
- **使用シナリオ**: 社内業務用アプリを従業員のデバイスに配布する際に利用され、App Storeを介さずに配布できます。

### プロビジョニングプロファイルの作成方法

プロビジョニングプロファイルはApple Developerアカウントの「Certificates, Identifiers & Profiles」ページで作成できます。

#### 作成手順

1. **Apple Developerにログイン**  
    Apple Developerのアカウントにログインし、「Certificates, Identifiers & Profiles」ページにアクセスします。

2. **IdentifiersでApp IDを作成**  
    プロビジョニングプロファイルの作成には、アプリのApp IDが必要です。事前に「Identifiers」セクションでApp IDを作成しておきます。

3. **Devicesでテストデバイスを登録**  
    - ![プロファイル追加画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/93c97587-f36a-37c6-c282-6e3c649a6f37.png)
    - ![App ID選択](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/48997e00-92d7-8d72-a62f-d20fef22ff76.png)
    - ![証明書選択](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/43b84aa5-0208-85d8-f376-a7b56fb09552.png)

    開発用やAd Hoc配布用の場合、デバイスのUDIDを登録する必要があります。「Devices」セクションでテストデバイスのUDIDを登録します。

4. **プロビジョニングプロファイルの作成**  
    「Profiles」セクションで「＋」ボタンをクリックして新しいプロビジョニングプロファイルを作成します。  
    作成するプロビジョニングプロファイルの種類（Development、Ad Hoc、App Store、In-House）を選択し、App IDや証明書、デバイスを選択して作成を完了します。

5. **ダウンロードとインストール**  
    ![プロファイルダウンロード](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/774c277f-c5cb-ccae-6ec3-928f0eba35eb.png)

    作成が完了したら、プロビジョニングプロファイルをダウンロードし、Xcodeで開発中のプロジェクトにインストールします。

### Xcodeでのプロビジョニングプロファイルの使用
プロビジョニングプロファイルはXcodeのプロジェクト設定で選択され、開発やテスト、配布のビルド設定に使用されます。
- **開発用プロビジョニングプロファイル**を使ってデバイスにインストールすると、そのデバイス上でのみアプリを動作させることができます。
- **App Store配布用プロビジョニングプロファイル**を使用してビルドしたアプリは、App Store経由で広く一般に公開され、誰でもインストール可能となります。

![プロビジョニングプロファイルの使用](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/5dbcb382-c567-0c39-0ef8-d92e515d0535.png)

そして、このプロビジョニングファイルに含まれる証明書の中の公開鍵と、macのキーチェーンアクセスに登録された秘密鍵を使い検証します。
![証明書と鍵の検証](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/1e1389c6-25b8-2390-b8b2-d5dfd630e091.png)

このとき、プロビジョニングの生成に使用したCSRファイルの中の公開鍵と一致する秘密鍵の情報および公開鍵の情報が不足していると以下のようなエラーになります。（または、証明書の期限が切れている場合などもこのエラーが発生します。）

![エラー画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/8188cae8-5f7a-b229-5227-2c716aa93868.png)

---

## 5. プッシュ通知用の追加証明書（p8形式のAPNsキー）

### APNsとp8キーの概要
iOSアプリでプッシュ通知を実現するためには、Apple Push Notification Service（APNs）とサーバー間で認証を行い、安全に通知を送信する必要があります。APNsはAppleが提供する通知サービスで、アプリのサーバーが送信した通知をiOSデバイスに直接配信します。このとき、APNsと通信するための追加の認証情報として、p8形式のAPNsキーを用います。

### Apple Push Notification Service（APNs）とは
**Apple Push Notification Service（APNs）**は、Appleが提供するクラウドベースのプッシュ通知配信サービスで、iOSやmacOSのデバイスにリアルタイムで通知を送信するためのインフラです。APNsは、アプリのバックエンドサーバーが送信する通知リクエストを受け取り、指定されたデバイスに通知を転送します。このサービスによって、ユーザーに対してアプリの更新情報やメッセージなどの通知がリアルタイムに提供されます。

### APNsと通信するためのサーバーと認証
APNsと安全に通信するには、サーバーが必要です。このサーバーは、APNsに対して認証を行い、許可された通知リクエストのみを送信します。認証は、Apple Developerアカウントで発行されるp8形式のAPNsキーを用いて行われます。

例えば、Firebaseが提供する通知配信サービス**Firebase Cloud Messaging（FCM）**を使用すると、FCMがAPNsにリクエストを送信し、通知の管理がしやすくなります。この場合、p8形式のAPNsキーをFirebaseに設定することで、APNsと安全に通信する準備が整います。

### p8形式のAPNsキー（Auth Key）とは
p8形式のAPNsキーは、APNsとサーバーの間で認証を行うための鍵です。このキーは、Apple Developerアカウントごとに1つ発行され、複数のアプリで共通して利用できるのが特徴です。また、有効期限がなく、定期的な更新が不要です。このキーを使用することで、**JWT（JSON Web Token）**を生成し、APNsへのトークンベースの認証を行います。

#### p8キーの特徴
- **Apple Developerアカウント全体で使用可能**: 1つのキーで複数のアプリの通知を管理可能
- **有効期限がない**: 通常の証明書とは異なり、再発行の必要がありません
- **JWTによる認証**: サーバーはJWTを生成し、APNsに安全に認証リクエストを送信します

### p8キーの作成方法
p8形式のAPNsキーはApple Developerアカウントで以下の手順で作成します。

1. **Apple Developerアカウントにログイン**
    - 「Certificates, Identifiers & Profiles」ページにアクセスします。

2. **Keysで新しいキーを作成**
    - 左メニューから「Keys」を選択し、「＋」ボタンをクリックして新しいキーを作成します。

3. **APNsの有効化**
    - 「Key Name」に任意の名前を入力し、「Apple Push Notifications Service (APNs)」を有効にして「Continue」をクリックします。
    ![Keys追加画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/b678d175-edd2-b7a3-16ec-d769bcff6196.png)

4. **p8キーのダウンロード**
    - キーの作成が完了すると、「Download」ボタンからp8形式のキー（例：AuthKey_XXXXXXXXXX.p8）をダウンロードします。
    - **注意**: p8キーは1度しかダウンロードできません。ダウンロード後は安全に保管してください。
    ![APNsキーのダウンロード](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/73c6be18-4928-a245-7e5b-f0fc2387287b.png)

5. **Key IDのメモ**
    - 作成したp8キーにはKey IDが割り当てられます。Key IDは認証の際に使用するため、メモしておきます。

### p8キーの配置と検証
ダウンロードしたp8キーは、APNsに通知を送信するサーバー（例: Firebase Cloud Messaging）に配置し、APNsと通信する際に使用されます。

#### Firebase Cloud Messagingでのp8キーの設定

1. **Firebaseにp8キーを設定**
    - Firebaseのプロジェクト設定でAPNsキーとしてp8ファイルをアップロードします。
    - また、Key IDとApple DeveloperアカウントのTeam IDも登録します。これによりFirebaseはAPNsと認証された通信を行えるようになります。

2. **JWTによる認証**
    - Firebaseは、サーバーからの通知リクエストをAPNsに送信する際、p8キーを用いてJWT（JSON Web Token）を生成し、トークンベースの認証を行います。
    - JWTには、Key ID、Team ID、発行時間などの情報が含まれており、APNsが正当なリクエストであることを確認します。

### APNsとの通信フロー

1. **通知リクエストの送信**
    - サーバー（例：Firebase Cloud Messaging）がp8キーを使用してJWTを生成し、APNsに通知リクエストを送信します。

2. **APNsでの認証と配信**
    - APNsはJWTの情報を基にリクエストの信頼性を確認し、認証が成功した場合、指定されたデバイスに通知を配信します。
    - 認証に失敗した場合、通知は拒否され、エラーメッセージが返されます。

このやりとりを図解すると以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/63ab115a-9abd-be88-312e-0c881d52c6d7.png)


---

## まとめ
以上が、Push通知を実装する上で必要となるApple Developer証明書の種類とその役割、手順についての詳細な説明です。各ステップをしっかりと理解し、正確に設定することで、安全かつ信頼性の高いPush通知機能をアプリに実装することが可能となります。

もし誤りや不明点があれば、コメントでご指摘いただけると幸いです。おつかれさまでした！

![全体像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287608/adf590ae-70af-2c97-c8d9-9727f7713773.png)

以下は参考にさせていただいた先人たちの偉大な記事たちです！
[iOSアプリ証明書（Apple Developer）概要](https://qiita.com/enjapan_common_user/items/7fb6ec3a4dd5fa7e7b82)
[CSR(証明書署名要求)とは？ わかりやすく10分で解説](https://www.netattest.com/csr-2023_mkt_tst)
[iOSアプリ証明書（Apple Developer）概要](https://qiita.com/enjapan_common_user/items/7fb6ec3a4dd5fa7e7b82)
[令和4年のPush通知を改めて整理する](https://zenn.dev/chocoyama/articles/5b07eead5ae0aa)
[【Swift】Firebaseからプッシュ通知を受け取るために最低限の実装をする(iOS15対応)](https://zenn.dev/tomsan96/articles/0cdfde2a49bfb2)