# Apple 푸시 알림 인증서: Expo에서 .p8과 .p12 중 선택

> Apple 푸시 알림에는 만료되지 않고 모든 앱에 쓰는 .p8 키와 1년마다 갱신하는 .p12 인증서가 있어요. Expo를 쓰면 EAS가 키를 관리해요.

원본 페이지: [Apple 푸시 알림 인증서: Expo에서 .p8과 .p12 중 선택](https://devoria.fr/ko/blog/apple-push-notification-certificate-p8-p12-expo)
작성자: [Mehdi Azizi](https://devoria.fr/ko/mehdi-azizi)
게시일: 2026-11-04
최종 내용 수정: 2026-11-04


Apple 푸시 인증서는 서버가 Apple의 알림 서비스인 APNs를 통해 내 앱에 알림을 보낼 수 있게 허가해 줘요. 형태는 두 가지예요. 1년 동안 유효하고 앱 하나에만 연결되는 .p12 인증서, 그리고 만료되지 않고 계정의 모든 앱에 쓸 수 있는 .p8 키예요. **Expo를 쓴다면 인증서는 필요 없어요. 첫 빌드 때 EAS가 .p8 키 생성을 제안하고, Expo 푸시 서비스가 그 키를 대신 사용해요.**

[개발자 인증서와 provisioning profile](https://devoria.fr/ko/blog/ios-certificate-provisioning-profile-expo) 가이드에서는 푸시 키를 몇 줄로만 다뤘어요. 이 글에서는 끝까지 파고들어요. 두 형식 중 무엇을 고를지, sandbox와 production 환경, 갱신, 그리고 TestFlight에서 알림이 끊기는 문제까지요.

저는 Expo와 EAS로 앱을 출시해요. Solys와 TradaZen은 설정에 `expo-notifications` 플러그인을 선언하고 있어요. 이 플러그인이 앱이 알림을 받을 수 있도록 준비해 줘요.

## Apple이 인증서나 키를 요구하는 이유

푸시 알림은 내 서버나 Expo 서버에서 출발해 APNs로 넘어가고, APNs가 iPhone에 전달해요. 그래서 APNs는 그 서버가 내 앱에 메시지를 보낼 권한이 있는지 확인해야 해요. Apple은 이를 증명하는 방법을 두 가지 제공해요.

- **.p8 키를 사용하는 토큰 기반 연결.** [Apple에 따르면](https://developer.apple.com/documentation/usernotifications/establishing-a-token-based-connection-to-apns) 더 빠르고, 여러 서버에서 쓸 수 있고, 키 하나로 팀의 모든 앱이나 일부 앱을 커버해요. 서버는 이 키로 토큰에 서명하는데, 적어도 한 시간마다 다시 만들어야 해요.
- **.p12 파일을 사용하는 인증서 기반 연결.** [Apple 설명에 따르면](https://developer.apple.com/documentation/usernotifications/establishing-a-certificate-based-connection-to-apns) 이 인증서는 앱 하나에만 연결되고 1년 동안 유효해요. 앱이 여러 개면 인증서도 여러 개예요.

[Apple의 만료 안내 페이지](https://developer.apple.com/support/expiration/)에도 나와 있듯이, APNs 토큰 서명 키는 절대 만료되지 않아요.

## .p8 / .p12 비교표

| 기준            | .p8 키              | .p12 인증서          |
| --------------- | ------------------- | -------------------- |
| 유효 기간       | 만료 없음           | 1년                  |
| 적용 범위       | 모든 앱             | 앱 하나              |
| 환경            | 생성 시 선택        | Sandbox와 production |
| 갱신            | 없음 (폐기 시 제외) | 매년                 |
| 다운로드        | 한 번만             | Mac에서 내보내기     |
| 개수            | 환경당 2개          | 앱당 1개             |
| Expo에서의 사용 | EAS가 생성하고 관리 | Expo 문서에 없음     |

세 가지를 짚고 갈게요. .p8 파일은 [한 번만 다운로드할 수 있어요](https://developer.apple.com/help/account/keys/create-a-private-key). Apple은 계정에 이 파일을 보관하지 않아요. 반면 .p12는 인증서를 만든 [Mac의 키체인에서 내보내요](https://developer.apple.com/help/account/capabilities/communicate-with-apns-using-a-tls-certificate). 그리고 환경당 키 2개 제한은 팀 키에 적용돼요. 특정 앱으로 제한된 키는 환경당 최대 200개까지 허용돼요.

[Expo의 자격 증명 페이지](https://docs.expo.dev/app-signing/app-credentials/)는 푸시 키만 다루고, 계정당 최대 2개라고 설명해요. 환경이나 앱별 키는 구분하지 않아요. **Expo 앱이라면 .p8 키가 정답이에요.**

## Sandbox와 production: 두 가지 환경

APNs에는 서버가 두 개 있어요. sandbox라고도 부르는 development, 그리고 production이에요. [Apple](https://developer.apple.com/documentation/usernotifications/sending-notification-requests-to-apns)은 앞쪽을 테스트용, 뒤쪽을 출시된 앱용으로 정해 두었어요. 앱은 `aps-environment` entitlement로 어느 쪽을 쓸지 알아요. [Apple에 따르면](https://developer.apple.com/documentation/bundleresources/entitlements/aps-environment) 이 값은 서명 프로필을 따라가요. 개발 프로필이면 `development`, 배포 프로필과 TestFlight면 `production`이에요.

**그래서 TestFlight 빌드는 App Store와 똑같이 production과 통신해요.**

Expo 쪽에서는 두 가지를 알아 두세요. [expo-notifications 문서](https://docs.expo.dev/versions/latest/sdk/notifications/)에 따르면 프로젝트에는 entitlement가 항상 `development`로 작성되고, 릴리스 빌드의 아카이브에서 `production`으로 바뀌어요. 그리고 Expo 토큰은 생성될 때 앱의 환경에 연결되는데, 이 환경은 자동으로 감지돼요. 보낼 때 따로 고를 건 없어요.

키를 직접 만든다면 Apple이 환경과 범위(팀 전체 또는 특정 앱)를 물어봐요. 개발자 문서에는 이제 sandbox나 production으로 제한된 팀 키가 설명되어 있고, 예전처럼 어디서나 쓸 수 있는 키도 계속 허용돼요. 그런데 [계정 도움말](https://developer.apple.com/help/account/capabilities/communicate-with-apns-using-authentication-tokens)에는 여전히 키가 두 환경 모두에 쓰인다고 적혀 있어요. Apple 문서끼리 말이 달라요. 생성할 때 고른 환경을 기억해 두세요. **sandbox 전용 키는 TestFlight에도 App Store에도 쓸 수 없어요.**

## Expo가 푸시 키를 관리하는 방식

2026년 7월 28일에 업데이트된 [Expo 설정 가이드](https://docs.expo.dev/push-notifications/push-notifications-setup/)에 따르면, 첫 개발 빌드 때 푸시 알림 설정과 APNs 키 생성을 제안해요. 둘 다 yes라고 답하세요. EAS Build를 쓰지 않는다면 `eas credentials`를 실행하세요. 유료 Apple Developer 계정이 필요해요.

그다음은 이렇게 돼요.

- **EAS가 키를 저장하고 앱에 연결해요.** Expo에 따르면 키 하나를 원하는 만큼 많은 앱에 쓸 수 있고, 새 키를 업로드해도 사용자의 Expo Push 토큰은 바뀌지 않아요.
- **내 서버는 APNs를 호출하지 않아요.** Expo 푸시 서비스로 보내면, 그쪽이 APNs로 전달해요. [Expo는 전송 후 약 15분 뒤에 영수증(receipt)을 확인하라고 해요](https://docs.expo.dev/push-notifications/sending-notifications/). 오류는 거기에 표시돼요.
- **플러그인이 entitlement를 추가해요.** `plugins`에 `expo-notifications`를 선언하세요.

```json
{
  "expo": {
    "plugins": ["expo-notifications"]
  }
}
```

함정이 두 가지 있어요. [Expo FAQ](https://docs.expo.dev/push-notifications/faq/)는 SDK 53부터 Expo Go가 푸시 알림을 더 이상 지원하지 않는다고 하는데, expo-notifications 페이지는 Android만 해당한다고 해요. 어느 쪽이든 Expo는 개발 빌드를 권장하니, 개발 빌드로 테스트하세요. 그리고 `eas credentials`로 키를 삭제하면 Expo 서버에서만 지워지고 Apple 계정에서는 지워지지 않아요. 자리를 비우려면 Apple 포털에서 폐기하세요. 다른 비밀 정보와 마찬가지로 .p8 파일은 절대 저장소에 들어가면 안 돼요. [Expo 앱의 API 키](https://devoria.fr/ko/blog/expo-app-secret-api-key-security)와 같은 규칙이에요.

## 갱신: 실제로 만료되는 것

**.p8 키는 갱신할 게 없어요.** 내가 폐기하지 않는 한 멈추지 않아요. 키가 유출됐다고 의심되면 [Apple은](https://developer.apple.com/help/account/capabilities/communicate-with-apns-using-authentication-tokens) 새 키를 만들고, 그 키로 전환한 다음에야 기존 키를 폐기하라고 권장해요. Expo에서 키를 교체하는 방법은 FAQ에 나와 있어요. `eas credentials`, iOS, 빌드 프로필을 차례로 선택한 뒤 푸시 키를 제거하고 새로 생성하면 돼요.

**.p12 인증서는 매년 만료돼요.** Apple은 만료 전에 갱신하고 키체인에서 날짜를 확인하라고 해요. 만료되거나 폐기되면 [앱에 더 이상 알림을 보낼 수 없어요](https://developer.apple.com/help/account/certificates/certificates-overview). Apple은 별도의 갱신 절차를 설명하지 않아요. 앱 식별자에서 새 인증서를 만들고, 만료 전에 서버에 설치한 다음, 기존 인증서를 제거하면 돼요. **가장 좋은 갱신 방법은 키로 넘어가는 거예요.**

> Intune이나 다른 기기 관리 도구로 iPhone을 관리하고 있나요? 그건 다른 인증서예요. 기기 관리용 푸시 인증서는 Apple Push Certificates Portal에서 만들고 매년 갱신해요. [Apple은](https://support.apple.com/guide/deployment/dep2de55389a) 사용한 Apple 계정을 기록해 두라고 권장해요. 갱신할 때 필요하거든요.

## 흔한 문제와 해결법

### 개발 환경에선 되는데 TestFlight에선 안 돼요

1. **잘못된 토큰으로 보내고 있어요.** TestFlight 빌드는 production에 등록되고 새 토큰을 받아요. 개발 빌드에서 받은 토큰은 작동하지 않아요. [토큰이 환경과 맞지 않으면](https://developer.apple.com/documentation/usernotifications/handling-notification-responses-from-apns) Apple은 `BadDeviceToken`을 반환해요. TestFlight 앱 자체에서 토큰을 가져오세요.
2. **production 앱에 푸시 자격 증명이 없어요.** Expo FAQ에 나오는 진단이에요. expo.dev의 프로젝트 자격 증명 페이지나 `eas credentials`로 확인하세요.
3. **키가 sandbox로 제한되어 있어요.** production에서 쓸 수 있는 키로 교체하세요.
4. **iPhone이 토큰을 받지 못해요.** Xcode 빌드 위에 TestFlight 빌드를 설치했다면 Expo는 기기를 재시작해 보라고 해요.

### "No valid aps-environment entitlement string found"

Expo FAQ에 따르면 이 오류는 iOS 프로젝트에 푸시 키가 설정되어 있지 않다는 뜻이에요. 자격 증명 페이지를 확인한 뒤 다시 빌드하세요. 그러면 EAS가 키 생성을 제안해요. `plugins`에 `expo-notifications`가 들어 있는지도 확인하세요.

### ITMS-90078: Missing Push Notification Entitlement

업로드 후에 Apple이 이 이메일을 보내요. 앱이 APNs에 등록하는 것처럼 보이는데 서명에 `aps-environment` entitlement가 없다는 내용이에요. [SDK 51에 관한 Expo 안내](https://github.com/expo/fyi/blob/main/apns-entitlement-sdk-51.md)에 설명이 있어요. 이 SDK부터는 `expo-notifications`가 설치된 경우에만 entitlement가 추가돼요. 이 경고는 Apple의 검사 두 가지에서 나와요. 첫째는 앱 식별자의 capability와 앱의 entitlement를 비교하는 검사예요. 둘째는 바이너리에서 알림 등록 메서드를 찾는 검사인데, Expo 코드는 모든 앱에 이 메서드를 포함하고 있어요.

**이건 경고일 뿐 리젝이 아니에요**, Expo도 그렇게 설명해요. 알림을 쓴다면 플러그인을 추가하고 다시 빌드하세요. [EAS는 빌드할 때마다 앱 식별자의 capability를 동기화해요](https://docs.expo.dev/build-reference/ios-capabilities/). 알림을 쓰지 않는다면 Apple 포털에서 식별자의 Push Notifications capability를 제거하세요. 경고가 계속 올 수도 있지만 아무 문제 없어요.

### InvalidCredentials 또는 모든 앱이 한꺼번에 조용해짐

영수증에 `InvalidCredentials`가 있다면 푸시 자격 증명이 더 이상 유효하지 않다는 뜻이에요. 대개 키가 폐기됐기 때문이에요. 그 키를 쓰던 모든 앱이 동시에 알림을 못 보내요. Expo의 해결법은 `eas credentials`를 실행하고 새 키를 만드는 거예요. 영수증에 `InvalidProviderToken`이 나온다면 Expo는 푸시 키와 프로필을 다시 생성하면서 새로 빌드하라고 권장해요.

## 알림을 켜기 전에

출시 전에 iPhone에서 알림을 테스트하려면 [TestFlight로 앱 테스트하기](https://devoria.fr/ko/blog/testflight-iphone-app-beta-testing)를 따라 하세요. 앱을 깨우는 무음 알림을 보낸다면 [백그라운드 모드에 관한 가이드라인 2.5.4](https://devoria.fr/ko/blog/guideline-2-5-4-background-mode-rejection)를 다시 읽어 보세요. Mac 없이 전체 과정을 진행하는 방법은 [Mac 없이 iOS 앱 출시하기](https://devoria.fr/ko/blog/publish-ios-app-without-mac-expo-eas)에, 출시 단계는 [App Store에 앱 출시하기](https://devoria.fr/ko/expertise/publish-app-on-app-store) 페이지에 있어요.

첫 전송 전에 [무료 진단](https://devoria.fr/ko/diagnostic)을 받아 보세요. 프로젝트에서 무엇이 막히는지 알려 주고, 제 Apple 리젝 방지 체크리스트도 보내 드려요. 앱을 만들고, 구독을 연결하고, 출시하는 과정은 [iOS & Android Kit](https://devoria.fr/ko/kits/ios)가 제 앱의 Starter Code와 함께 4단계로 안내해요. 내 속도에 맞춰 진행하면 돼요.

## 자주 묻는 질문

### Apple 푸시 인증서는 만료되나요?

.p12 인증서는 1년 후에 만료되고, 교체하지 않으면 알림이 멈춰요. .p8 키는 절대 만료되지 않아요. 내가 폐기할 때만 멈춰요. 이게 키를 선호하는 가장 큰 이유예요.

### 앱마다 푸시 인증서가 필요한가요?

.p12 인증서라면 그래요. 인증서 하나는 앱 하나에만 연결돼요. .p8 키는 계정의 모든 앱에 쓸 수 있어요. 그래서 Expo에서는 키 하나로 모든 앱을 커버할 수 있어요.

### Apple 푸시 인증서는 어떻게 갱신하나요?

새 인증서 서명 요청으로 앱 식별자에서 새 인증서를 만들고, 서버에 설치한 다음, 기존 인증서를 제거하세요. 만료 전에 하세요. 가장 간단한 방법은 갱신이 필요 없는 .p8 키로 넘어가는 거예요.

### .p8 파일을 잃어버렸어요. 어떻게 해야 하나요?

Apple은 한 번만 다운로드할 수 있게 해요. EAS가 키를 만들었다면 Expo가 보관하고 있으니 알림은 계속 작동해요. 그렇지 않다면 새 키를 만들어 `eas credentials`로 추가한 다음, Apple 포털에서 기존 키를 폐기하세요. 사용자의 Expo Push 토큰은 바뀌지 않아요.

### 푸시 키를 바꾼 뒤에 다시 빌드해야 하나요?

보통은 아니에요. 키는 설치된 앱이 아니라 알림을 보내는 서버에서 쓰이고, Expo는 새 키가 토큰을 바꾸지 않는다고 설명해요. 예외는 영수증에 `InvalidProviderToken`이 나올 때예요. 이 경우 Expo는 새 키와 새 프로필로 다시 빌드하라고 권장해요.


## 내 프로젝트

[Review Kit](https://devoria.fr/ko/kits/app-review): 제 App Store 심사 체크리스트, 수정해서 통과한 Apple 리젝 사례, Google Play 체크리스트, Claude Code 스킬 3개를 담았어요. ₩73,000.

[iOS & Android Kit](https://devoria.fr/ko/kits/ios): Claude Code로 iPhone·Android 앱을 만들어 보세요. 제 앱들의 시작 코드, 스토어 출시까지의 과정, 모든 키트를 담았어요. ₩148,000.

[진단: 내 아이폰 앱까지 남은 거리](https://devoria.fr/ko/diagnostic): 7개 질문, 60초. 아이폰 앱 출시를 진짜 가로막는 게 뭔지, 4단계 로드맵, 나에게 맞는 키트까지 알려드려요.
