APNs証明書とは|取得・更新手順とAPNs-410/403エラーの原因別対処
APNs証明書は、自社のサーバー(プロバイダ)がAppleのプッシュ通知基盤に接続するための鍵です。つまずく場所はだいたい決まっていて、「アプリ用の証明書とMDM用の証明書を取り違える」「1年で切れることを忘れて通知が止まる」「送信したら410や403が返ってきて意味が分からない」の3つに集約されます。この記事では、取得手順そのものよりも、この3つを迷わず切り分けられる形でApple公式の記述に沿って整理します。
まとめ
- APNs証明書には系統が2つある。アプリのプッシュ通知用(Apple Developerで発行する
.p12)と、MDMがデバイスを管理するため用(Apple Push Certificates Portalで発行)。発行元も用途も別物で、片方の手順をもう片方に当てはめると必ず行き詰まる。 - 証明書はどちらも有効期限1年。アプリ用は更新運用そのものを無くせるので、新規実装なら期限のない
.p8トークン認証を選ぶべき。 - APNs-410は「そのデバイストークンはもう有効ではない」の意味で、レスポンスの
timestamp(ミリ秒)より前に取得したトークンは破棄してよい。送信を止めるのが正しい対処で、証明書の問題ではない。 - APNs-403は逆に、デバイスではなく証明書・認証トークン側の問題(期限切れ、環境違い、JWTの期限切れなど)。410と403で見る場所が真逆になる。
- 2025年2月のAPNsサーバー証明書のCA更新は、自社の
.p12を再発行する話ではない。プロバイダサーバー側のトラストストアに新しいルート証明書を入れる話で、「証明書の更新」という言葉から自社証明書のことだと誤読しやすい。
以下、それぞれの根拠と手順を順に見ていきます。
2系統あるAPNs証明書:アプリ用とMDM用の違い
APNs(Apple Push Notification service)は、Appleが運用するプッシュ通知の配信基盤です。登場人物は3者で、通知を送りたい自社サーバー(プロバイダ)、中継するAPNs、受け取るiPhoneやMacというデバイスが並びます。プロバイダがAPNsに接続するときの身分証明が「APNs証明書」で、デバイスはAPNsと常時接続を維持しているため、アプリが起動していなくても通知が届きます。
問題は、「APNs証明書」という一語が用途の異なる2種類を指していることです。検索して出てくる手順が食い違って見えるのは、たいていこの混同が原因です。
| 項目 | アプリ用(APNs SSL証明書) | MDM用(APNsプッシュ証明書) |
|---|---|---|
| 発行場所 | developer.apple.com | identity.apple.com |
| 目的 | 自社サーバーからアプリへ通知を送る | MDMがiOS/macOSデバイスを管理する |
| 紐づく単位 | App ID(Bundle ID) | 組織のAppleアカウント1つ |
| 有効期限 | 1年 | 1年(365日) |
| 切れたときの影響 | 通知が送れない | デバイス管理が効かなくなる |
| 代替手段 | .p8トークン認証(期限なし) | なし(毎年更新が必須) |
iOSアプリを開発していて「プッシュ通知を実装したい」ならアプリ用です。Intune・Jamf・mobiconnectなどのMDMを導入していて「Apple Push Certificates Portalにサインインしろ」と指示されたならMDM用で、こちらはアプリ開発とは無関係です。以降、章ごとにどちらの話かを明示します。
アプリ用:証明書ベース(.p12)とトークンベース(.p8)の選択基準
アプリ用には、証明書で接続する方式と、認証トークン(JWT)で接続する方式の2つがあります。新規に組むならトークンベース(.p8)を選ぶのが合理的です。理由は運用コストで、Appleは署名キーについて「The signing key doesn’t expire, but can be revoked.」(署名キーは期限切れにならないが失効はさせられる)と記しており、年1回の更新作業が構造的に不要になります。1つのキーを複数アプリに使い回せ、開発環境と本番環境の両方で機能する点も、証明書にはない利点です(Apple公式ヘルプ「Communicate with APNs using authentication tokens」)。速度面でも公式は、トークン方式のステートレスな通信は証明書ベースより速いと説明しています。
証明書ベースを選ぶ理由が残るのは、既存のプロバイダ実装やプッシュ配信サービスが.p12しか受け付けない場合と、VoIPやWatchKit向けに専用証明書が必要な場合です。逆に言えば、それ以外で証明書ベースを新規採用する積極的な理由はありません。
なお、.p8キーはダウンロードできるのが発行時の1回だけです。取得したファイルを失うと再ダウンロードできず、キーを作り直すことになります。
アプリ用APNs証明書の取得手順(Apple Developer)
証明書ベースを使う場合の流れです。Apple Developer Programの有料メンバーシップ(日本は円建て請求で、金額は地域により異なる。法人登録には組織のD-U-N-S番号が必要)が前提になります。
- CSRを作る:Macのキーチェーンアクセスで「証明書アシスタント」→「認証局に証明書を要求」。メールアドレスと通称を入れ、「ディスクに保存」を選ぶと
CertificateSigningRequest.certSigningRequestが生成される。このとき秘密鍵がローカルのキーチェーンに残るので、後で書き出すMacを変えないこと。 - App IDでPush Notificationsを有効にする:Certificates, Identifiers & Profiles → Identifiers で対象のBundle IDを開き、Push Notificationsのケイパビリティにチェックを入れる。
- 証明書を発行する:Certificates → + →「Apple Push Notification service SSL (Sandbox & Production)」を選び、対象App IDを指定してCSRをアップロード。発行された
.cerをダウンロードする。 - .p12に書き出す:
.cerをダブルクリックしてキーチェーンに取り込み、対応する秘密鍵とセットで選択して「書き出す」→.p12形式で保存。プロバイダサーバーにはこの.p12(とパスフレーズ)を設定する。
トークンベースを選ぶ場合はCSRもApp IDへの紐づけも不要で、Keys(キー)から「Apple Push Notifications service (APNs)」を有効にしたキーを作り、.p8とKey ID・Team IDの3点をプロバイダに渡すだけで済みます。Firebase Cloud Messaging経由でiOSへ通知を送る構成でも、Firebaseコンソールに登録するのはこの.p8(またはAPNs証明書)です。FCMの仕組みそのものはFCM(Firebase Cloud Messaging)とは|プッシュ通知の仕組みと使い方をわかりやすく解説で扱っています。
MDM用APNsプッシュ証明書の取得と更新
こちらはMDM製品の運用担当者向けです。発行はApple Push Certificates Portal(identity.apple.com)で行い、MDM側が出力したCSRをアップロードして.pemを受け取り、MDMに登録します。CSRはSHA-2署名である必要があり、SHA-1では発行されません。
更新時のアカウント固定:再登録リスクの回避
MDM証明書は、更新を誤ったときの影響がもっとも大きい場所です。ポータルで既存証明書の「Renew」を押すのではなく、新しい証明書を新規作成してしまうと、既存の管理対象デバイスとの紐づけが切れます。Microsoft Learnは、MDMプッシュ証明書は作成に使ったApple Accountに紐づいており、同じアカウントで更新するよう明記しています。証明書を削除して作り直した場合はデバイスをリセットして再登録する必要がある、とも書かれています。Apple側も配置ガイドで、更新時に必要になるため作成に使った管理対象Appleアカウント(推奨)またはApple Accountを控えておくよう促しています。
実務上の対策は単純で、作成に使ったアカウント(個人のApple Accountではなく、組織で共有できる管理対象Appleアカウントを使うのが公式の推奨)と有効期限を、担当者個人ではなく組織の資産として台帳に残すことです。期限切れ後もMicrosoft Learnの記述では30日の猶予期間がありますが、猶予に頼る運用は勧められません。個人アカウントで作ってしまった証明書を管理対象Appleアカウントへ移す手続きはApple窓口経由で可能とされていますが、最大10営業日かかるため期限直前には間に合いません。
APNsのレスポンスコード別トラブルシューティング
通知が届かないとき、原因の切り分けはAPNsが返すHTTPステータスとreason文字列を読むところから始まります。プロバイダAPIのレスポンスは公式に定義されており、ステータスごとに「疑うべき場所」がはっきり分かれます。
| ステータス | 公式の意味 | 疑う場所 |
|---|---|---|
| 200 | 成功 | ―(届かないなら端末設定側) |
| 400 | 不正なリクエスト | デバイストークン・トピック・ヘッダ |
| 403 | 証明書または認証トークンのエラー | 証明書・.p8・JWT |
| 404 | :path が不正 | リクエストURL |
| 405 | :method が不正(POSTのみ可) | HTTPメソッド |
| 410 | そのトピックでトークンが無効 | デバイストークン(送信停止) |
| 413 | ペイロード超過 | 通知本文のサイズ |
| 429 | 同一トークンへの過剰なリクエスト | 送信頻度・トークン更新頻度 |
| 500 | APNs内部エラー | リトライ(時間を空けて再送) |
| 503 | サーバー停止中で利用不可 | リトライ(指数バックオフ) |
APNsが返すのはこの範囲だけです。検索されることのある「apns-409」は公式のステータス一覧に存在しないため、409を受け取ったなら間に挟まっているプロキシや配信SDK側が返している可能性を先に疑ってください。以下、実際に問い合わせの多い410・403・400を個別に見ます。
APNs-410(Unregistered / ExpiredToken):送信停止が正しい対処
410は「The device token is no longer active for the topic.」=そのトピックに対してデバイストークンがもう有効ではない、という意味です。reasonはUnregistered(そのトピックでトークンが非アクティブ)とExpiredToken(トークンが期限切れ)の2種類があり、どちらも指し示す状況は同じで、アプリが削除された、ユーザーが端末を初期化した、といったケースで返ります。公式はUnregisteredの説明で「同じデバイストークンへこれ以上プッシュを送る必要はない」と述べており、正しい対処はリトライではなく、そのトークンを配信対象から外すことです。410を無視して送り続けると、無効トークンが溜まって配信基盤の効率が落ちます。
実装上の要点は、410のレスポンスボディにだけ含まれるtimestampです。これは「APNsがそのトピックでトークンの無効を確認した時刻」で、単位はミリ秒(Epochからの経過ミリ秒)です。秒として扱うと1970年付近の日時になってしまうので注意してください。この時刻より前に取得したトークンは破棄してよく、この時刻より後にアプリが再登録して取得した同じトークンは有効と判断します。単に「410が来たら即削除」ではなく、トークンの取得時刻とtimestampを比較して削除するのが公式の想定です。
APNs-403の切り分け:証明書・認証トークン側
403は「証明書またはプロバイダの認証トークンにエラーがある」ことを示します。デバイストークンの問題ではないので、ここでデバイス側を調べても時間を溶かすだけです。reasonで原因が絞れます。
BadCertificate:証明書が無効。期限切れの証明書を使い続けているケースが典型。BadCertificateEnvironment:クライアント証明書が接続先の環境と一致していない(開発用の証明書で本番エンドポイントに繋いだ等)。ExpiredProviderToken:JWTが古い。APNsはタイムスタンプが1時間以上前のトークンを拒否するため、生成し直す必要がある。InvalidProviderToken:トークンが無効、または署名を検証できない。Key ID・Team ID・.p8の組み合わせ違いで頻発する。MissingProviderToken:証明書も使わずauthorizationヘッダも付けていない。UnrelatedKeyIdInToken/BadEnvironmentKeyIdInToken:後述するTopic-specific key・Team-scoped keyを導入したときに現れる。キーが対象トピックと無関係、またはキーの環境(開発/本番)が接続先と食い違っている。
JWTの扱いには落とし穴があります。有効期間は1時間ですが、Appleは更新頻度を「20分に1回より頻繁にせず、60分に1回より疎にしない」と定めています。毎リクエストでJWTを作り直す実装にすると、403ではなく429のTooManyProviderTokenUpdatesで弾かれます。生成したトークンは20〜60分の範囲でキャッシュして使い回してください。署名アルゴリズムはES256のみで、RS256は使えません。
APNs-400の典型:トークンとトピックの不一致
400で頻出するreasonはBadDeviceTokenとDeviceTokenNotForTopicです。どちらも実際の原因は環境の取り違えであることが大半で、開発ビルドで取得したデバイストークンを本番エンドポイント(api.push.apple.com)へ送る、あるいはその逆をやっています。公式もBadDeviceTokenの説明で、トークンが接続先の環境と一致しているか確認するよう促しています。
そのほか、複数トピックに対応した証明書で接続しているのにapns-topicヘッダを付けなかった場合はMissingTopic、そのトピックへの送信が許可されていない場合はTopicDisallowedが返ります。BadPriorityやInvalidPushTypeのようにヘッダの値そのものが不正なケースも400です。
有効期限と更新運用
アプリ用の証明書についてAppleは「Provider certificates are valid for a year and must be updated to continue communicating with APNs」と記しています。1年で切れ、切れればAPNsとの通信が続けられません。期限はキーチェーンアクセスで確認でき、公式も「サービス停止を避けるため、期限が切れる前に更新すること」としています。
更新の手順は初回発行と同じで、CSRを作り直して新しいAPNs SSL証明書を発行し、.p12を書き出してプロバイダサーバーの設定を差し替えます。旧証明書が有効なうちに新証明書へ切り替えれば、通知の停止時間はゼロにできます。期限切れを事故なく回避するなら、証明書の有効期限をカレンダーやサーバー監視に登録し、失効30日前に通知が飛ぶようにしておくのが現実的です。
ただし、これは証明書ベースを使い続ける限り毎年発生する作業です。期限切れ事故を根本的に無くしたいなら、更新運用を続けるのではなく.p8トークン認証へ移行するほうが早い、というのが結論になります。
2025年2月に追加されたキー種別:Team-scoped と Topic-specific
トークン認証には2025年2月17日の告知で2種類のキーが追加されました。Team-scoped keyは開発・本番のどちらか一方の環境に限定できるキーで、各環境あたり最大2個まで作成できます。Topic-specific keyは特定のBundle IDに紐づけるキーで、Sandbox・Production各200個まで、1キーあたり最大400トピックを扱えます。
従来のキーは全トピック・全環境で使えるため、漏えいすると影響範囲が組織全体に及びました。新しい2種は影響範囲を環境やアプリ単位に絞り込むための仕組みです。既存のキーはそのまま動き続けるとAppleが明言しているので、慌てて移行する必要はありません。判断基準を挙げるなら、本番キーを外部の配信ベンダーに渡している場合や、複数チームで1つのDeveloperアカウントを共有している場合はTopic-specific keyに切り替える価値があります。単一アプリを自社サーバーだけで運用しているなら、従来のキーのままで実害はありません。導入後に403のUnrelatedKeyIdInTokenやBadEnvironmentKeyIdInTokenが出たら、キーのスコープと送信先が食い違っているサインです。
接続要件とリクエストヘッダ
プロバイダサーバーの接続仕様は次の通りです。レガシーのバイナリプロトコルは2021年3月31日でサポート終了しており、現在はHTTP/2ベースのプロバイダAPIのみです。
- 本番:
https://api.push.apple.com/開発:https://api.sandbox.push.apple.com - ポートは443。社内ファイアウォールで443が使えない場合は2197も利用できる
- HTTP/2とTLS 1.2以降が必須。パスは
/3/device/<device_token>、メソッドはPOSTのみ - ペイロード上限は4KB(VoIPは5KB)
curl -v --http2 \
--header "apns-topic: com.example.MyApp" \
--header "apns-push-type: alert" \
--header "authorization: bearer $JWT" \
--data '{"aps":{"alert":"test"}}' \
https://api.sandbox.push.apple.com/3/device/$DEVICE_TOKEN
$JWTは.p8をES256で署名して生成したもので、20〜60分ごとにローテーションします。--http2を使うにはHTTP/2対応でビルドされたcurl(nghttp2リンク済み)が必要で、curl --versionの機能一覧にHTTP2が出ない環境では動きません。
ヘッダで誤解が多いのがapns-push-typeです。日本語の解説では「iOS 13以降は必須」と書かれることがありますが、Apple公式の記述は「watchOS 6以降では必須、macOS・iOS・tvOS・iPadOSでは推奨(recommended)」です。実装として付けるべきなのは変わりませんが、「付けていないから即エラー」ではない点は切り分け時に効いてきます。apns-topicはBundle IDで、通知種別に応じたサフィックスが付きます。apns-expirationに0を指定すると1回だけ配信を試みて保存せず、0以外なら最大30日間APNsが保持して再送します。apns-priorityは10が即時(既定)、5が省電力に配慮した配信でバックグラウンド通知は常に5、1は端末の電力を最優先してユーザーを起こさない配信です。
2025年のAPNsサーバー証明書更新は「自社証明書の更新」ではない
2024年10月17日、AppleはAPNsのサーバー証明書を新しい認証局のものに切り替えると告知しました。切り替え日はSandboxが2025年1月20日、本番が2025年2月24日です。この告知は「APNs証明書の更新」という言葉から自社の証明書を再発行する話だと誤読されやすいのですが、まったく別の話です。
この変更で必要なのは、プロバイダサーバー側のトラストストアに新しいルート証明書(SHA-2 Root: USERTrust RSA Certification Authority)を追加することです。Appleは告知の中で「現時点で、Appleから発行されたAPNs SSLプロバイダ証明書を更新する必要はありません」と明記しています。つまり自社の.p12は無関係で、対応すべきなのはAPNsへ接続する側のサーバーがAPNsの新しいサーバー証明書を検証できるかどうか、という点だけです。
影響が出るのは、OSのルート証明書ストアを更新していない古いサーバーや、ルート証明書をアプリケーションに埋め込んで固定している(証明書ピンニングをしている)実装です。心当たりがあるなら、サーバーのCA証明書パッケージ(Linuxならca-certificates)が最新かを確認してください。なお、本記事執筆時点(2026年7月)でApple Developerの「Upcoming Requirements」から確認できるAPNs関連の必須対応告知は、この2025年2月24日のCA更新が最後です。
よくある質問
APNsとは何ですか?
Apple Push Notification service の略で、Appleが運用するプッシュ通知の配信基盤です。開発者のサーバー(プロバイダ)がAPNsへ通知を送り、APNsがiPhoneやiPad、Mac、Apple Watchへ配信します。アプリが起動していなくても通知を届けられるのは、各デバイスがAPNsと常時接続を維持しているためです。
APNs証明書の有効期限はどれくらいですか?
アプリ用のAPNs SSL証明書もMDM用のプッシュ証明書も1年です。一方、トークン認証で使う.p8署名キーには有効期限がなく、失効させない限り使い続けられます。期限切れによる通知停止を避けたい場合は.p8への移行が根本対策になります。
APNs-410はどう対処すればよいですか?
そのデバイストークンが無効になったという意味なので、リトライせず配信対象から外します。レスポンスに含まれるtimestamp(ミリ秒)より前に取得したトークンだけを削除し、それ以降に再取得された同じトークンは有効として扱ってください。証明書側の問題ではありません。
APNs証明書とMDMのプッシュ証明書は同じものですか?
別物です。アプリ用はApple Developerで発行してアプリのBundle IDに紐づき、MDM用はApple Push Certificates Portal(identity.apple.com)で発行して組織のアカウントに紐づきます。MDM用は作成時と同じアカウントで更新しないとデバイスの再登録が必要になる恐れがあるため、作成に使ったアカウントと有効期限は担当者の記憶ではなく組織の台帳に残してください。
開発用(Sandbox)と本番用の証明書は分ける必要がありますか?
現在Apple Developerで発行できる「Apple Push Notification service SSL (Sandbox & Production)」は両環境に対応した1枚の証明書です。分ける必要はありませんが、接続先エンドポイントは開発がapi.sandbox.push.apple.com、本番がapi.push.apple.comと別なので、デバイストークンを取得した環境と送信先の環境は必ず揃えてください。ここがずれると400のBadDeviceTokenや403のBadCertificateEnvironmentが返ります。