.p12 file, then run openssl pkcs12 -in pushcert.p12 -out pushcert.pem -nodes -clcerts in Terminal.Why this happens
Apple Push Notification service (APNs) servers traditionally authenticate provider servers using mutual TLS (mTLS) over an HTTP/2 connection. This handshake requires an X.509 certificate paired with an RSA private key, formatted as a Privacy-Enhanced Mail (.pem) file containing base64-encoded ASCII data.
The friction occurs because Apple does not distribute .pem files or private keys directly. When you create an APNs certificate in the Apple Developer portal, Apple only issues a public certificate (.cer) based on your Certificate Signing Request (CSR). The corresponding private key remains exclusively in your Mac’s local keychain.
To construct a usable .pem file for your backend server or notification provider, you must pair the public certificate with your private key inside macOS Keychain Access, export the pair as a PKCS #12 (.p12) archive, and convert that archive using command-line OpenSSL. Recent versions of OpenSSL also introduce encryption compatibility issues with .p12 files generated by modern versions of macOS.
How to fix it
1. Generate the PEM file manually using Keychain and OpenSSL
This standard workflow extracts the certificate and private key from your Mac and compiles them into a single unencrypted .pem payload.
Step A: Generate a Certificate Signing Request (CSR)
- Open Keychain Access on your Mac.
- In the menu bar, choose Keychain Access > Certificate Assistant > Request a Certificate From a Certificate Authority.
- Enter your email address and a Common Name (for example,
YourApp APNs Production). - Leave CA Email Address empty.
- Select Saved to disk, click Continue, and save the file (it will have a
.certSigningRequestextension).
Step B: Create and download the certificate in Apple Developer
- Sign in to your account at developer.apple.com and navigate to Certificates, Identifiers & Profiles.
- Select Certificates in the sidebar, then click the blue plus button (+).
- Under Services, select Apple Push Notification service SSL (Sandbox & Production) and click Continue.
- Select your app’s explicit App ID from the dropdown menu and click Continue.
- Click Choose File, select the
.certSigningRequestfile you generated in Step A, and click Continue. - Click Download to obtain your
.cerfile (for example,aps.cer).
Step C: Install and export the .p12 archive
- Double-click the downloaded
aps.cerfile to import it into your login keychain in Keychain Access. - Under the Certificates category, locate the newly imported certificate. It will be named
Apple Push Services: <your.bundle.id>(orApple Development IOS Push Services:for sandbox-only). - Click the disclosure arrow next to the certificate to reveal the associated private key.
- Highlight both the certificate and the private key by holding the Command (
Cmd) key and clicking each item. - Right-click the selection and choose Export 2 items….
- Choose Personal Information Exchange (.p12) as the file format, name it
pushcert.p12, and save it to your desktop. - When prompted for an export password, enter a password you can remember (or leave it blank if your workflow allows it), then enter your macOS administrator password when prompted to authorize exporting the private key.
Step D: Convert the .p12 file to .pem
Open Terminal and navigate to your desktop:
cd ~/Desktop
Run the following OpenSSL command to extract both the certificate and the private key into a single .pem file:
openssl pkcs12 -in pushcert.p12 -out pushcert.pem -nodes -clcerts
If you are using modern OpenSSL 3.x (such as an installation from Homebrew) and see error:0308010C:digital envelope routines::unsupported, Apple’s legacy RC2/PBE encryption used in .p12 exports is not enabled by default. Pass the -legacy flag to resolve this:
openssl pkcs12 -in pushcert.p12 -out pushcert.pem -nodes -legacy
Once the command finishes, verify that pushcert.pem exists and contains both a -----BEGIN CERTIFICATE----- block and a -----BEGIN PRIVATE KEY----- (or -----BEGIN RSA PRIVATE KEY-----) block.
2. Automate creation with Fastlane PEM
If you already use Fastlane or want to bypass the manual portal and Keychain steps entirely, the pem action automates the CSR generation, Apple Developer upload, download, and .pem compilation in a single command.
To generate a production APNs .pem file:
fastlane pem -a com.example.yourApp -u your-apple-id@example.com
To generate a sandbox development certificate:
fastlane pem --development -a com.example.yourApp -u your-apple-id@example.com
Fastlane downloads the certificate, pairs it with the newly generated private key, and outputs both a .p12 and a .pem file in your active directory.
3. Alternative: Migrate to APNs Authentication Tokens (.p8)
Unless your backend service strictly requires legacy mTLS .pem certificates, Apple strongly recommends using APNs authentication tokens (.p8 keys) over certificates.
Using an APNs Auth Key has three major advantages:
– No annual expiration: APNs SSL certificates expire every 12 months and require regenerating .pem files. Auth keys do not expire until you explicitly revoke them.
– Universal access: A single .p8 key works for all apps associated with your Apple Developer Team across both Development and Production environments.
– Simpler deployment: You download the .p8 text file directly from Apple without needing Keychain Access, CSRs, or OpenSSL conversion.
To generate a modern .p8 key instead:
1. In your Apple Developer account, navigate to Certificates, Identifiers & Profiles > Keys.
2. Click the plus button (+) to register a new key.
3. Enter a Key Name and check the box for Apple Push Notifications service (APNs).
4. Click Continue, then click Register.
5. Click Download to save your .p8 file. Record your Key ID and your Team ID for your server configuration.
How to prevent it
- Migrate to
.p8tokens: Switch server configurations to APNs token-based authentication to eliminate yearly certificate expirations and manual OpenSSL conversions. - Export both items: Always verify that you select both the certificate and its nested private key before exporting from Keychain Access; exporting only the certificate will produce a
.pemfile that cannot sign TLS connections. - Back up the original CSR and key: If you must use certificates, store the private key in a secure credential vault so team members can regenerate
.pemfiles without reissuing certificates. - Check OpenSSL versions: Check whether your shell environment runs macOS system LibreSSL (
/usr/bin/openssl) or Homebrew OpenSSL 3 (/opt/homebrew/bin/openssl), and include the-legacyflag if using OpenSSL 3 with Keychain exports.
FAQ
How do I verify my APNs PEM file is valid?
You can inspect the contents using OpenSSL. Run openssl x509 -in pushcert.pem -noout -text to view the certificate expiration date and bundle identifier, and run openssl rsa -in pushcert.pem -check to confirm the private key is intact.
Can I use the same PEM file for sandbox and production?
No. If you generate a dedicated Development APNs certificate, it will be rejected by the production APNs gateway (api.push.apple.com). However, the combined “Apple Push Notification service SSL (Sandbox & Production)” certificate type can connect to both gateways if your backend targets the respective endpoint.
Why does my backend report an invalid certificate error even though the PEM file was created?
This typically occurs when the .pem file is missing the private key. Open the .pem file in a text editor and ensure it contains both -----BEGIN CERTIFICATE----- and -----BEGIN PRIVATE KEY----- sections.
Parts of this guide are adapted from content licensed under CC BY-SA 4.0; this article is shared under the same license.
