跳转至正文
iOS 安全 教程

iOS 证书与描述文件详解

详解 iOS 证书与描述文件:证书与描述文件类型、如何配合使用、.p12 文件、UDID、过期及签名错误。

Apple 开发者门户中的签名证书和描述文件

iOS code 签名由两部分组成。一个 证书 证明应用由谁构建,而 描述文件 指明它是哪个应用、哪些设备可以运行,以及可以使用哪些能力。除非证书、私钥和匹配的描述文件全部对应一致,否则 Xcode 会拒绝为设备构建,App Store Connect 也会拒绝上传。

本指南会解释每个部分、开发、ad hoc、TestFlight、App Store 和企业构建分别需要哪种组合、如何在没有 Mac 或有 Mac 时创建它们,以及如何修复你会遇到的错误。

为什么 Apple 要求 code 签名

Apple 只允许 iPhone 运行能追溯到已知开发者的 code。签名给 Apple 三项保证:

  1. 身份:二进制文件由特定 Apple Developer 团队的成员签名。
  2. 完整性:签名后没有人修改过二进制文件。改动一个字节就会破坏签名。
  3. 授权:该应用获准在此设备上运行,并拥有这些权限(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 应用进行签名时,它会检查:

  1. 你的 Target 中的 Bundle ID(例如 com.example.app)与 Profile 中的 App ID 一致。
  2. 用于签名的证书是 Profile 中列出的证书之一。
  3. 该证书的私钥可以在 Keychain 中找到。
  4. 对于开发版和 ad hoc 构建,设备的 UDID 已包含在 profile 中。
  5. 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 上手动创建

  1. 打开 钥匙串访问 > 证书助理 > 从证书颁发机构请求证书。输入您的邮箱,选择 保存到磁盘。这会在您的钥匙串中创建私钥,并生成一个 .certSigningRequest 文件。
  2. 在 Apple Developer 门户中,前往 证书、标识符和描述文件 > 证书 > +,选择 Apple Distribution (或 Apple Development),并上传 CSR。
  3. 从 Firebase Console 下载 .cer 并双击它。钥匙串访问会将其与私钥配对。
  4. 若要导出用于 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

  1. 标识符 > +: 用完全一致的 bundle ID 注册 App ID,并启用你用到的 capabilities(Push Notifications、Sign in with Apple、Associated Domains…)。
  2. 设备 > +: 对于 development 和 ad hoc 描述文件,请注册每位测试者的 UDID。测试者可以直接在手机上用 iOS UDID 查询工具获取,无需 Mac 或数据线。
  3. 描述文件 > +: 选择描述文件类型、App ID、证书和设备。给它起个清晰的名字,例如 com.example.app AppStore 2026.
  4. 从 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。

后续步骤

为 Capacitor 应用提供 Live Updates

当 Web 层出现线上 Bug 时,通过 Capgo 发布修复,而不用等 App Store 审核好几天。用户会在后台收到更新,原生变更则仍走正常审核流程。

博客最新动态

Capgo 为你提供打造真正专业的移动应用所需的最有价值的洞察。