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 类型 | 用途 | 设备限制 |
|---|---|---|
| Development | Xcode 真机调试 | 最多 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。
- 安装 P12 到 Keychain:用
security import命令 - 设置解锁钥匙串:否则 Xcode 打包会卡死
- 匹配 Provisioning Profile:要么从 Apple Developer API 动态下载,要么预先放到项目仓库
这里要提一个坑:不同环境的证书千万别混。我有个同事为了省事,把 Development 证书拿来打 Release 包,结果 App Store 审核直接被打回,原因是签名与 Provisioning Profile 不匹配。
4.5 证书生命周期与自动续签
证书和 Profile 都有有效期。个人开发和公司团队最头疼的就是「证书过期→打包失败」。苹果现在支持自动续签?其实只针对部分情况。我建议大家在 CI 里加一个告警——比如在证书到期前 30 天发通知。
我的做法是写一个脚本,每天检查钥匙串里所有 iOS 证书的过期时间,如果小于 30 天就发 Slack 消息。具体代码不复杂,但能救你一命。
4.6 整体签名流程(SVG)
下面这张图把从 CSR 生成到 CI 打包的关键环节串了起来。你仔细看一遍,应该能建立完整的认知。
4.7 常见问题与避坑指南
- 导出 P12 时没勾选「包含私钥」——结果 CI 上签名失败。
- Provisioning Profile 和证书不匹配——Xcode 报 "No matching provisioning profiles"。
- 钥匙串没有提前解锁——CI 任务一直卡在 "Code Signing" 超时。
- Distribution 证书私钥丢失——只能重新生成并更新所有 Profile,影响上线时间。
其实签名这件事,说难也不难。你只要记住:证书证明身份,Profile 证明授权,P12 是移动证书的便携格式。在 CI 里做好隔离、过期监测,就不会手忙脚乱。