iOS code 签名由两部分组成。一个 证书 证明应用由谁构建,而 描述文件 指明它是哪个应用、哪些设备可以运行,以及可以使用哪些能力。除非证书、私钥和匹配的描述文件全部对应一致,否则 Xcode 会拒绝为设备构建,App Store Connect 也会拒绝上传。
本指南会解释每个部分、开发、ad hoc、TestFlight、App Store 和企业构建分别需要哪种组合、如何在没有 Mac 或有 Mac 时创建它们,以及如何修复你会遇到的错误。
为什么 Apple 要求 code 签名
Apple 只允许 iPhone 运行能追溯到已知开发者的 code。签名给 Apple 三项保证:
- 身份:二进制文件由特定 Apple Developer 团队的成员签名。
- 完整性:签名后没有人修改过二进制文件。改动一个字节就会破坏签名。
- 授权:该应用获准在此设备上运行,并拥有这些权限(push、iCloud、Sign in with Apple、App Groups 等)。
证书提供前两项,描述文件提供第三项。
构建基石
| 组件 | 是什么 | 文件 | 所有者 |
|---|---|---|---|
| 私钥 | 密钥对中的私密部分,在你的机器上生成 | 存储在 Keychain 中或 .key / .pem |
你。Apple 永远看不到它 |
| CSR | 包含你公钥的证书签名请求 | .certSigningRequest / .csr |
临时性 |
| 证书 | 与您的团队绑定的 Apple 签名公钥 | .cer |
由 Apple 签发,由您下载 |
| 签名身份 | 证书与私钥的组合 | .p12 导出时 |
您 |
| 应用 ID | 您的 Bundle ID 及已启用的 Capabilities | 开发者门户记录 | 团队 |
| 设备 | 已注册的 iPhone 或 iPad UDID | 开发者门户记录 | 团队 |
| 描述文件 | 包含 App ID、允许的证书、设备及 Entitlements 的集合 | .mobileprovision |
团队 |
最常见的误区: .cer 单个文件本身是没用的。签名需要创建 CSR 时使用的私钥。如果丢失了该私钥,则需要重新创建证书。
证书类型
Apple 开发
用于在开发期间通过 Xcode 在自有设备上运行构建。开发证书属于个人开发者,Apple 会用电脑名称来标记。团队中的每位开发者都可以拥有自己的开发证书。
Apple 分发
用于为 Ad Hoc 分发、TestFlight 和 App Store 的构建签名。分发证书属于团队,只有 Account Holder 或 Admin 角色可以创建。Apple 对团队可持有的证书数量有限制,因此建议通过安全存储共享同一张证书,而不是让每个开发者各自创建。
你可能仍会看到 iOS 开发 以及 iOS 发布证书与描述文件详解 出现在旧账号中。这些是 Xcode 11 之前的类型。Apple Development 和 Apple Distribution 已取代它们,并可在 iOS、iPadOS、macOS、tvOS、watchOS 和 visionOS 上使用。
你可能还会遇到其他证书类型
- Developer ID 应用程序 / 安装程序:用于在 Mac App Store 之外分发的 Mac 应用。不适用于 iOS。
- Apple 推送通知服务 SSL:旧版推送证书。建议优先使用 APNs 身份验证密钥 (
.p8),它不会每年过期,且适用于团队中的所有 App。请参阅我们的 APNs 证书指南. - Apple Pay 商户身份 (Merchant Identity), Pass 类型 ID, 网站推送 ID:特定服务。
Provisioning profile 类型
| Profile 类型 | 证书 | 设备 | 用途 |
|---|---|---|---|
| iOS App 开发 | Apple 开发 | 仅限已注册设备 | 在 Xcode 中运行、调试 |
| Ad Hoc 分发 | Apple Distribution | 仅限已注册设备(每个会员年每个设备系列最多 100 台) | 通过链接或文件在测试设备上安装 Release 构建 |
| App Store Connect | Apple 分发 | 任何设备,通过 Apple | TestFlight 和 App Store |
| 企业内部 | 企业分发证书 | 组织内的任意设备 | 仅限 Apple Developer Enterprise Program |
一个配置文件绑定 一个 App ID。如果你的应用包含扩展(如小组件、通知服务扩展、共享扩展),每个 target 都有独立的 bundle ID,并需要各自的配置文件。
各部分如何协同工作
当 Xcode 或构建服务对您的 Capacitor 应用进行签名时,它会检查:
- 你的 Target 中的 Bundle ID(例如
com.example.app)与 Profile 中的 App ID 一致。 - 用于签名的证书是 Profile 中列出的证书之一。
- 该证书的私钥可以在 Keychain 中找到。
- 对于开发版和 ad hoc 构建,设备的 UDID 已包含在 profile 中。
- Entitlements 文件(push、associated domains、App Groups)是 App ID 和 profile 所允许内容的子集。
如果任何检查失败,你会收到签名错误而非运行时崩溃,这很好:你可以在发布前发现问题。
我需要哪种组合?
| 目标 | 证书 | 个人资料 | 设备注册 |
|---|---|---|---|
| 通过 Xcode 在自己的 iPhone 上运行 | Apple 开发 | iOS App 开发 | 是 |
| 无需 TestFlight 即可把 build 发给少数测试人员 | Apple Distribution | Ad Hoc 分发 | 是,每个测试人员的 UDID |
| 用 TestFlight 做 Beta 测试 | Apple Distribution | App Store Connect | 否 |
| 在 App Store 上发布 | Apple Distribution | App Store Connect | 否 |
| 内部员工应用,无需上架 App Store | 企业版 | 企业内部 | 否 |
TestFlight 使用 相同的 签名方式,和 App Store 一样。TestFlight 没有独立的配置文件。你只需上传一个 build,然后在 App Store Connect 中决定是将其发送给测试人员、提交审核,还是两者兼有。
创建证书和描述文件
方案 1:让 Xcode 管理签名
本地开发时,这是最简单的方式。打开 ios/App/App.xcworkspace (或 .xcodeproj 当你的 Capacitor 8 项目使用 Swift Package Manager 时,请选择 应用 目标,打开 签名与能力,勾选 自动管理签名 并选择你的团队。Xcode 会为你创建开发证书、注册已连接的设备,并生成描述文件。
在 CI 中,自动签名会变得很麻烦,因为构建机器需要访问团队账户并自行创建证书。大多数团队在发布构建时会改用手动签名,或改用基于 API 密钥签名的构建服务。
方案 2:在 Mac 上手动创建
- 打开 钥匙串访问 > 证书助理 > 从证书颁发机构请求证书。输入您的邮箱,选择 保存到磁盘。这会在您的钥匙串中创建私钥,并生成一个
.certSigningRequest文件。 - 在 Apple Developer 门户中,前往 证书、标识符和描述文件 > 证书 > +,选择 Apple Distribution (或 Apple Development),并上传 CSR。
- 从 Firebase Console 下载
.cer并双击它。钥匙串访问会将其与私钥配对。 - 若要导出用于 CI:在钥匙串访问中,位于 我的证书,右键点击证书,选择 导出,另存为
.p12,并设置一个强密码。
方案 3:无需 Mac 即可创建
你也可以在 Linux 或 Windows 上使用 OpenSSL 完成整个流程:
# 1. Private key and CSR
openssl genrsa -out ios_distribution.key 2048
openssl req -new -key ios_distribution.key -out ios_distribution.csr \
-subj "/emailAddress=you@example.com/CN=Example Inc/C=US"
# 2. Upload ios_distribution.csr in the Apple Developer portal,
# download the certificate as distribution.cer
# 3. Convert the .cer (DER) to PEM
openssl x509 -in distribution.cer -inform DER -out distribution.pem -outform PEM
# 4. Build the .p12 (signing identity)
openssl pkcs12 -export -inkey ios_distribution.key -in distribution.pem \
-out ios_distribution.p12 -legacy
本指南中介绍的 -legacy 这个 flag 在 OpenSSL 3 中很关键:不加它, .p12 使用的加密算法会被 macOS keychain 工具拒绝,即使密码正确也会报错“invalid password”。
如果你不想安装 OpenSSL, iOS 证书生成器 它会为你创建 CSR 和私钥。它们来自不存储它们的无状态 Capgo 端点,且只有它的 .cer 改为 .p12 转换器完全在浏览器中运行。如果你的策略要求密钥必须在本机生成,请使用上面的 OpenSSL 命令。
创建 Provisioning Profile
- 标识符 > +: 用完全一致的 bundle ID 注册 App ID,并启用你用到的 capabilities(Push Notifications、Sign in with Apple、Associated Domains…)。
- 设备 > +: 对于 development 和 ad hoc 描述文件,请注册每位测试者的 UDID。测试者可以直接在手机上用 iOS UDID 查询工具获取,无需 Mac 或数据线。
- 描述文件 > +: 选择描述文件类型、App ID、证书和设备。给它起个清晰的名字,例如
com.example.app AppStore 2026. - 从 Firebase Console 下载
.mobileprovision文件。
如果你之后添加了设备或功能,必须重新生成并重新下载描述文件。现有描述文件不会自动更新。
检查描述文件
一套 .mobileprovision 该文件是已签名的 plist。在 macOS 上可以这样读取:
security cms -D -i App_Store.mobileprovision > profile.plist
/usr/libexec/PlistBuddy -c "Print :Name" profile.plist
/usr/libexec/PlistBuddy -c "Print :ExpirationDate" profile.plist
/usr/libexec/PlistBuddy -c "Print :Entitlements" profile.plist
/usr/libexec/PlistBuddy -c "Print :ProvisionedDevices" profile.plist
在 Linux 上, openssl smime -inform der -verify -noverify -in App_Store.mobileprovision 会打印出 plist 内容。
要检查构建出的 .ipa 是用什么签名的:
unzip -q App.ipa -d ipa
codesign -dvv ipa/Payload/App.app
codesign -d --entitlements :- ipa/Payload/App.app
有效期与续期
- 证书 自创建之日起有效期为一年。
- Provisioning Profile 一年后过期;若其中包含的证书过期或被吊销,则提前失效。
- App Store 应用继续正常运行 分发证书过期后,Apple 会为 App Store 下载重新签名。只有上传新构建时才需要新证书。
- Ad Hoc 和开发构建将无法启动 一旦描述文件过期,测试人员会看到应用启动时崩溃。
- TestFlight 构建 上传后 90 天过期,与证书无关。
- 企业应用将无法使用 当企业证书过期或被吊销时,每台设备都会受影响。请在到期前续期。
- 设备名额 每个会员年度可重置一次。移除设备不会释放其名额,直到下一个会员年度开始。
把证书到期日加到共享日历里。我们的 证书管理指南 会更深入地介绍监控和轮换。
常见错误及解决方法
“未找到签名证书 ‘iOS Distribution’” 或 “签名证书无效”:私钥不在这个钥匙串中。请导入 .p12,或者如果没人持有该密钥,就创建一个新证书。
“Provisioning profile 不包含签名证书”:该描述文件是使用其他证书创建的。请在门户中编辑该描述文件,勾选当前证书,然后重新生成并下载。
“描述文件不包含当前选中的设备”:注册 UDID,然后重新生成 profile。TestFlight 或 App Store 不需要此操作。
“Provisioning profile 不支持 Push Notifications capability”:在 App ID 上启用该 capability,然后重新生成 profile。Profile 是快照。
“未找到此可执行文件的有效 provisioning profile” 安装时:设备不在 ad hoc profile 中,或者 profile 已过期。
App 安装后立即闪退:在 iOS 16 及更高版本中,development 和 ad hoc build 需要设备开启 Developer Mode。请参阅 如何在 iOS 上开启 Developer Mode.
Extensions 签名失败:每个 extension target 都需要独立的 App ID 和 profile。请检查 Signing & Capabilities 中的所有 target,而不仅仅是 App。
导入在 Linux 上生成的 .p12 文件时提示 “Invalid password”:使用以下命令重新构建: openssl pkcs12 -export ... -legacy.
SDK 版本上传被拒绝:自 2026 年 4 月起,App Store Connect 要求使用 Xcode 26 和 iOS 26 SDK 构建。请更新 Xcode 或你的 CI 镜像。Capacitor 8 已要求使用 Xcode 26。
团队协作最佳实践
- 每个团队仅需一个 Apple Distribution 证书,并将其存储为
.p12存放在密码管理器或 secrets store 中,密码单独保存。 - 切勿通过电子邮件发送
.p12文件或将其提交到 git。 - 使用 App Store Connect API 密钥 (
.p8) 进行上传,而不是使用 Apple ID 密码。 - 使用 bundle ID、类型和年份为 profile 命名。
- 吊销离职成员的证书。
- 记录一份清单,包含 App 使用的所有 bundle ID、extension 和 capability。
为 Capacitor 应用提供云端签名
发布 iOS build 时,并不需要每位开发者桌上都备一台 Mac。 Capgo 构建 在 Capgo 的 macOS 机器上为 Capacitor 应用执行 build,使用 .p12 你提供的 profile。凭据仅用于 build,不会存储在 Capgo 服务器上。只需在 CLI 中保存一次即可:
bunx @capgo/cli@latest build credentials save --appId com.example.app --platform ios
bunx @capgo/cli@latest build request com.example.app --platform ios --path .
本指南中介绍的 Capgo Build iOS 文档 列出了具体的凭据选项,包括用于 TestFlight 上传的 App Store Connect API 密钥,以及 ad_hoc 用于测试版 build 的模式。
一旦你的第一个 build 进入 TestFlight,你就可以向用户推送 JavaScript 和资源变更, Capgo 实时更新 无需为每次修复都重新签名新的二进制文件。Native code 变更和新功能仍需通过商店发布签名 build。
后续步骤
- 需要先有账号吗? 如何创建 Apple 和 Google Play 开发者账号.
- 准备好把构建交给测试人员了吗? 如何将 iOS 和 Android 应用分发给测试人员.
- 准备提交?请阅读我们的 iOS 应用提交指南.