4. iOS 签名与证书:Apple Development / Distribution 证书、Provisioning Profile、P12 文件

做 iOS 开发的朋友都知道,签名是绕不开的一道坎。我刚开始带 CI 流水线时,就因为证书配置翻过车——打包出来 local 能装,TestFlight 却报签名无效。说白了,搞懂这三样东西:证书、Provisioning Profile、P12,你的 iOS 签名体系就稳了一半。

4.1 Apple 证书体系:Development vs Distribution

苹果把证书分成两大类:Development(开发)和 Distribution(发布)。

  • Development 证书:用于真机调试、Xcode 直接跑。说白了就是「自己玩」的证书。
  • Distribution 证书:用于提交 App Store、打 Ad Hoc / Enterprise 包。所有对外交付的包都必须用它签。

我个人习惯在 Apple Developer Center 里直接创建 CSR。记得密钥长度选 2048 位,别手滑选错了。为什么强调这个?我以前遇到过有人选了 1024 位,结果 Xcode 死活报错,折腾一上午才发现。

4.2 Provisioning Profile:连接证书与设备的「通行证」

光有证书还不够。苹果要求每个安装包必须绑定一个 Provisioning Profile,它里面包含了:

  • 使用的证书(Development 或 Distribution)
  • 可安装的设备列表(仅 Development / Ad Hoc)
  • App ID(Bundle Identifier)
  • 允许的能力(Capabilities,比如 Push Notification)

我做过一个项目,测试组反馈某个环境装不上包。查了一圈发现是 Provisioning Profile 里忘记加新同事的设备 UUID。嗯,这种坑踩过一次就长记性了。

Profile 类型用途设备限制
DevelopmentXcode 真机调试最多 100 台
Ad Hoc内测分发(非 App Store)最多 10000 台
App Store提交审核 / 发布不限制
Enterprise企业内部分发不限制

4.3 P12 文件:证书的「便携版」

证书本身是 .cer 格式,但 CI 服务器(比如 Jenkins、GitLab Runner)需要的是带私钥的 P12 文件。怎么来的?从钥匙串里导出:

// 在 Mac 钥匙串中导出
// 找到对应的证书(Development 或 Distribution)
// 右键 → 导出「...」→ 格式选 .p12
// 设置导出密码(记住它!)

我建议所有团队统一用一个强密码,并把它存到 CI 的环境变量或加密仓库里。我曾经见过有人把密码贴在 Jenkins 控制台的明文参数里……后来项目被安全审计时差点除名。

4.4 CI 中如何管理这些证书

CI 流水线要处理的事情无非是:把正确的证书安装到打包机 Keychain,匹配正确的 Provisioning Profile。

  1. 安装 P12 到 Keychain:用 security import 命令
  2. 设置解锁钥匙串:否则 Xcode 打包会卡死
  3. 匹配 Provisioning Profile:要么从 Apple Developer API 动态下载,要么预先放到项目仓库

这里要提一个坑:不同环境的证书千万别混。我有个同事为了省事,把 Development 证书拿来打 Release 包,结果 App Store 审核直接被打回,原因是签名与 Provisioning Profile 不匹配。

核心原则:每套环境(Debug / Release / Enterprise)使用独立的证书 + Provisioning Profile + P12,互不干扰。

4.5 证书生命周期与自动续签

证书和 Profile 都有有效期。个人开发和公司团队最头疼的就是「证书过期→打包失败」。苹果现在支持自动续签?其实只针对部分情况。我建议大家在 CI 里加一个告警——比如在证书到期前 30 天发通知。

我的做法是写一个脚本,每天检查钥匙串里所有 iOS 证书的过期时间,如果小于 30 天就发 Slack 消息。具体代码不复杂,但能救你一命。

提示:Distribution 证书的私钥一旦丢失无法恢复。请把 P12 文件备份到安全存储(比如 HashiCorp Vault 或 AWS KMS),不要只放在本地。

4.6 整体签名流程(SVG)

下面这张图把从 CSR 生成到 CI 打包的关键环节串了起来。你仔细看一遍,应该能建立完整的认知。

iOS 证书与签名核心流程 ② 生成 CSR ① Mac 钥匙串 ③ 提交 CSR Apple Developer Center ④ 下载 .cer Development / Distribution ⑤ 导出 P12 带私钥的便携文件 ⑥ 创建 Profile 选择证书+设备+App ID ⑦ CI 打包 安装 P12 + Profile CI 多环境管理实践 Debug 环境 Development 证书 Development Profile Release 环境 Distribution 证书 App Store Profile Enterprise 环境 Distribution 证书 Enterprise Profile 每个环境使用独立的 P12、证书、Profile,同一台打包机通过解锁对应钥匙串实现隔离

4.7 常见问题与避坑指南

⚠ 我曾经遇到的几个坑:
  • 导出 P12 时没勾选「包含私钥」——结果 CI 上签名失败。
  • Provisioning Profile 和证书不匹配——Xcode 报 "No matching provisioning profiles"。
  • 钥匙串没有提前解锁——CI 任务一直卡在 "Code Signing" 超时。
  • Distribution 证书私钥丢失——只能重新生成并更新所有 Profile,影响上线时间。

其实签名这件事,说难也不难。你只要记住:证书证明身份,Profile 证明授权,P12 是移动证书的便携格式。在 CI 里做好隔离、过期监测,就不会手忙脚乱。