ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

iOS生产证书过期更新全流程:从报错到恢复上架的实操记录

iOS生产证书过期更新全流程:从报错到恢复上架的实操记录 iOS生产证书过期更新全流程从报错到恢复上架的一次完整实操记录搞iOS开发最怕遇到什么不是Bug不是审核被拒而是项目要提审或者要出包的时候突然发现生产证书过期了。Xcode直接甩给你一个Provisioning profile is expired或者certificate has expired后台也进不去推送连不上整个人瞬间就麻了。这篇文章把我这次处理iOS生产证书过期的完整过程整理了一遍包括证书体系的基本逻辑、过期前的症状判断、具体的更新操作步骤、以及几个特别容易踩的坑。不管你是独立开发者还是公司团队里负责上架的兄弟照着这套流程走基本都能解决问题。1. 先搞明白iOS证书是怎么回事1.1 证书不是只有一个是一整套体系很多人一听到证书过期就想着去开发者后台重新生成一个但实际操作的时候会发现事情没那么简单。iOS的签名机制里跟你直接相关的是两类东西证书Certificate和描述文件Provisioning Profile它们之间是绑定关系不是独立的。证书相当于你的开发者身份证明证明你是这个Apple Developer账号的合法成员它分为开发证书Development和生产证书Distribution。生产证书下面又分两类一个是App Store和Ad Hoc共用的Distribution证书另一个是推送专用的APNs证书。描述文件则是把证书、App ID、设备如果是Ad Hoc打包在一起的一个配置文件它本身也有有效期。关键点在这里描述文件的有效期不会超过它关联的证书有效期。也就是说如果你的Distribution证书过期了就算描述文件显示的到期日期还没到它实际上也已经失效了。很多人在后台看到描述文件还没过期就以为没问题其实是个误区。1.2 为什么证书会过期Apple为什么不搞成永久有效的从根上说这是Apple对安全性的设计选择。证书不是一次性发给你就完事了它包含了一对公私钥私钥留在你的钥匙串里公钥和你的身份信息一起被Apple签名后发给你。密钥本身有被暴力破解的风险有效期就是给开发者一个强制轮换密钥的周期避免一个密钥用了五年八年被泄露后影响整个生态。生产证书的有效期目前是3年开发证书是1年描述文件一般是1年。底层逻辑是证书负责证明你是谁描述文件负责声明你能干什么两者都设有效期任何一环断了签名链路就断了。1.3 证书过期后对已经上架的App有什么影响这个问题我特意先说清楚因为它关系到你判断问题的严重程度。已经上架App Store的App不会因为证书过期而无法下载或无法运行。用户手机上运行的是已经打包好的二进制文件App Store里的下载分发不依赖你开发者账号里的证书状态。但是以下几个事情会受影响提交新版本审核会失败因为上传包的时候就过不了签名校验推送服务APNs会挂掉用户收不到推送无法生成新的描述文件也无法在Xcode里Archive出新的包TestFlight内部测试会中断测试人员装不了新版本所以证书过期不是App下架级别的灾难但它是你这段时间没法更新和运营级别的麻烦。如果正好赶上版本迭代的节骨眼几乎等同于项目停摆。2. 怎么判断你的证书是不是真的过期了2.1 开发者后台怎么查登录Apple Developer后台进入Certificates, Identifiers Profiles页面在Certificates选项卡下能看到你账号下所有的证书列表。每一行会显示证书名称、类型、过期日期和状态。如果你看到状态栏是红色的Expired那基本就是它了。需要特别留意的是后台是有筛选器的默认可能只显示All或者某种状态。如果你没找到过期的证书试着把筛选改成Expired。很多人在这一步卡住不是证书不存在而是被筛选条件挡住了。2.2 钥匙串Keychain怎么看打开钥匙串访问在登录钥匙串的我的证书分类里找到带有Apple Worldwide Developer Relations Certification Authority签发的证书。如果证书显示此证书已过期或者有效期那栏是红色说明本地存储的证书已经失效。这里有个细节钥匙串里可能同时存在多个相同名称的证书。因为很多开发者每年续一次证书旧的没删新的又加了你无法一眼判断哪个是当前生效的。建议以开发者后台的状态为准钥匙串只用来确认私钥是否存在。2.3 Xcode和推送服务的报错实操中你可能根本不会先去后台查而是直接被报错拦住。常见的几种情况Xcode里选择签名时提示App requires a provisioning profile但其他项目签名正常Archive成功后上传到App Store Connect时提示Missing or invalid signature服务器端的推送服务日志出现BadCertificate或者InvalidToken推送消息发不出去如果你同时遇到推送失败和构建报错先别急着排查代码优先去后台看一眼证书状态大概率是证书过期这个一票否决的问题。3. 更新证书的完整实操流程3.1 第一步确认证书类型别误删打开后台找到过期的那个证书先看它的类型。如果是Distribution证书它是App打包签名用的记录一下它关联了哪些App ID。如果是APNs证书它可能只对应某个特定Bundle ID的推送服务。强烈建议把证书列表截图存一份因为你接下来要撤销Revoke旧证书撤销后证书立即失效没有后悔药。截图是为了万一后面哪里对不上还能对照参考。3.2 第二步在钥匙串中生成新的CSR文件打开钥匙串访问在菜单栏选择证书助理 → 从证书颁发机构请求证书。这一步对应英文界面的Certificate Assistant Request a Certificate From a Certificate Authority。在弹出的窗口里填两个关键信息电子邮件地址建议填开发者账号的主邮箱实际上填什么不影响后台签发但最好保持有记录常用名称填一个你能认出来的名字比如CompanyName Distribution 2025方便后续在后台和钥匙串里识别选择存储到磁盘点击继续会生成一个CertificateSigningRequest.crt文件。这个CSR文件本质上就是你的公钥加上一些身份信息Apple后台拿到它之后会用Apple的私钥对这个CSR签名把它变成真正的开发者证书。提示生成CSR用的私钥是自动保留在钥匙串里的。如果你在这台电脑上生成CSR之后却换了一台电脑去下载证书新证书也能下载但安装后你会找不到对应的私钥等于一张锁打不开的锁。所以生成CSR和最终使用证书尽量保持在同一个环境中。3.3 第三步撤销旧证书在开发者后台的Certificates列表中找到过期的证书点击进入详情页找到Revoke按钮点击确认撤销。这一步有两个作用。一是把旧的证书从签名体系里彻底移除避免它在系统中残留影响后续判断。二是新的证书和旧证书在同一个App ID下只能存在一个有效的你不撤销旧的有时候会导致描述文件关联混乱。实操提醒如果你有多个App共用一个Distribution证书撤销之后要赶紧把新证书生成并配置好因为这段时间里团队其他成员如果用旧证书去构建会直接报签名错误。3.4 第四步创建新证书并下载在Certificates页面点击右上角的号进入创建向导。选择证书类型这里要注意如果你是要打包上架用选择Apple Distribution现在后台已经把App Store和Ad Hoc合并成这一个了如果你是要做推送服务选择Apple Push Notification service SSL (Sandbox Production)现在它支持一个证书同时用于开发和生产环境下一步会让你上传CSR文件选择刚才保存的.crt文件点击继续。Apple后台会立即生成证书整个过程通常只要几秒钟。生成后点击下载会得到一个.cer文件。双击.cer文件它会自动导入到钥匙串中。导入后在钥匙串里应该能看到你新证书的Common Name也就是你填的那个常用名称它的签发者是Apple Worldwide Developer Relations Certification Authority有效期从当天开始。3.5 第五步更新描述文件证书更新了描述文件必须同步更新。回到Profiles页面找到受影响的描述文件进入详情页。你会看到描述文件关联的证书列表里旧证书可能还是已选中状态新证书已经出现在列表里。此时直接点击Edit在新证书前打勾保存即可。不用重新创建描述文件原地编辑就能完成绑定更新。保存之后回到列表页把编辑过的描述文件下载下来文件格式是.mobileprovision。3.6 第六步把证书和描述文件装进Xcode下载好的描述文件如果Xcode开着可能已经自动同步了。如果没有最简单的办法是双击.mobileprovision文件系统会自动放到~/Library/Developer/Xcode/UserData/Provisioning Profiles/目录下Xcode重启后就能识别。如果你用的是Xcode自动签名模式理论上只要证书和描述文件都在Xcode会自动选择正确的组合。但从我的实操经验来看自动签名没有你想的那么自动偶尔会出现Xcode选中了过期描述文件的情况。这种时候手动在Build Settings里找到Signing Certificate和Provisioning Profile选项强制指定成新证书和新描述文件然后Clean一下项目再Build基本都能解决。3.7 第七步验证是否生效更新完成后用真机进行一次完整的Archive操作确认签名不再报错。步骤如下Xcode里选择Any iOS Device (arm64)作为目标设备Product菜单 → ArchiveArchive完成后在Organizer或者Xcode 13的窗口管理器里看签名状态应该显示Valid或者没有红色警告如果要确认推送证书是否生效这个不通过Xcode看得去服务器端操作后面会单独说。4. 容易被忽略的几个坑4.1 私钥丢了新证书装上了也没用这是最普遍的一个问题特别是接手别人项目的时候。后台里的证书记录还在但原来生成证书的电脑已经换了私钥没导出带过来。此时即使你下载了新证书并双击安装钥匙串里只有公钥信息没有对应的私钥Xcode打包时依然会报签名错误Codesign阶段提示no identity found。判断方法很简单在钥匙串里选中新证书展开小箭头如果看不到私钥子项说明私钥缺失。解决办法有两个从旧电脑的钥匙串里导出私钥右键选择导出格式选.p12导入到新电脑如果旧电脑已经没了只能重新生成CSR → 撤销旧证书 → 重新创建证书走一遍完整流程养成习惯每次生成证书后用.p12备份私钥放到安全的地方。因为CSR只能生成一次私钥没法通过证书反推私钥。4.2 描述文件看起来没到期但其实已经失效描述文件的到期日期可能比证书晚但它的有效性受证书最短有效期约束。也就是说证书过期那天描述文件跟着失效。后台的Profiles页面状态可能显示Active但你实际使用它去签名系统会提示无效。认证失效根本原因在证书不在描述文件。所以排查的时候第一眼先看证书到期时间别被描述文件的日期迷惑。这也是我刚才强调先确认证书类型和过期的原因。4.3 推送证书更新后服务器端也要跟着换APNs证书过期的问题比普通证书更隐蔽。你在后台更新了新证书后服务器端用的还是旧证书。很多团队把证书管理得随随便便换证书这件事开发知道运维不知道结果推送还是挂。服务器端用.p12的话需要把新证书和私钥导出成.p12然后替换服务器上的配置文件同时重启推送服务。如果你用的是.pem格式从新证书导出时可以用以下命令openssl pkcs12 -in new_cert.p12 -out new_cert.pem -nodes -clcerts然后把新的.pem部署到推送服务节点覆盖旧文件。别忘了同时更新服务器上的证书过期监测告警逻辑一般在推送服务的配置文件里都有证书路径和有效期参数。4.4 团队多人协作时的证书坑如果团队里有多个人共同使用一个开发者账号证书更新后其他人本地的钥匙串里没有新证书的私钥他们一拉代码就发现构建失败。这时候不用每个人都去后台下载证书只需要把新证书导成.p12文件发给团队其他人让他们双击导入到各自的钥匙串里。或者更靠谱的做法是借助脚本在构建阶段自动检测证书状态并输出提示避免成员在不知情的情况下强行打包。还有一种情况团队里有人误操作把所有人的Distribution证书都撤销了导致所有App的签名全部失效。这种情况预防大于补救建议在开发者后台搞一个证书管理规范明确谁能操作后台、撤销证书前必须通知全员、私钥必须统一存在一个共享钥匙串里。5. 实操中遇到的问题排查与记录5.1 Xcode提示没有找到证书但后台明明有我这次遇到的第一个问题就是这个。后台Distribution证书状态是Active钥匙串里也有对应私钥但Xcode的Signing Capabilities里就是报No signing certificate found。排查过程先在钥匙串里确认证书是否真的存在于本机的login钥匙串里而不是系统钥匙串里。如果只在系统钥匙串里Xcode有时读不到。把证书从系统钥匙串拖到登录钥匙串锁定状态取消重新打开Xcode问题就解决了。还有一次是证书导入的时候系统自动放到了系统分类导致Xcode的codesign阶段找不到身份。右键查看证书详情确认信任设置为使用系统默认值如果被改成了始终信任反而可能导致校验异常。5.2 Archive成功后上传App Store Connect报ITMS-90164ITMS-90164 Invalid Provisioning Profile这个错误我以前犯过。原因是描述文件里的证书是新证书但Archive时Xcode用的还是旧证书。简言之构建时签名配置乱了。解决办法是在Xcode里执行Product Clean Build Folder快捷键ShiftCmdK然后删除Derived Data重启Xcode再次Archive。如果还不行检查Build Settings里的Code Signing Identity不要用Automatic手动选成新证书的名字然后Provisioning Profile也强制指定新描述文件。5.3 更新后推送还是发不出去这个也是老问题。后台证书更新了服务器端的.p12也换了推送还是报BadDeviceToken排查半天才发现是推送的TopicBundle ID写错了。APNs证书本身和App ID是绑定的如果证书对应的是com.xxx.app服务器发送时也要带这个Topic不能拿旧App ID的配置直接套用。还有一种是时间不同步。服务器时间和APNs服务器时间差异过大会导致证书验证失败。NTP同步一下服务器时间然后重启推送服务通常能解决。5.4 常见问题速查表问题现象可能原因处理方式Xcode报Provisioning profile expired描述文件过期或关联证书过期后台更新描述文件并重新下载codesign报no identity found钥匙串缺少对应私钥导入p12或重新生成证书上传报ITMS-90164构建时使用了旧描述文件Clean 手动指定签名配置推送收不到后台显示BadCertificate服务器端证书未更新替换p12/pem并重启推送服务后台证书状态Active但Xcode不识别证书存在系统钥匙串而非登录钥匙串拖到登录钥匙串并取消锁定描述文件状态Active但签名失败证书有效期已绑定失效检查关联证书的过期时间5.5 防坑习惯常备无患处理完这次证书过期我给自己定了几条规矩建议你也照做第一登录开发者后台看所有证书和描述文件的到期时间做成一张Excel表设好提醒在到期前30天、7天分别提醒一次。Apple一般会在到期前发邮件但邮件容易被忽略尤其是有多个开发者账号时。第二凡是生成证书第一件事就是从钥匙串导出.p12备份文件名里带上用途和日期比如dist_cert_com_xxx_2025.p12。同时把密码记在密码管理器里不要写在代码提交信息里。第三证书和描述文件的更新流程写进团队的交接文档或者新人入职指南里。别觉得这是小事断一次推送服务或者卡一次提审代价比写文档大得多。第四有条件的话给描述文件做一套自动化检测脚本在CI/CD流程的构建阶段检查本机证书是否在有效期内提前拦截问题。例如在xcodebuild之前执行一条安全工具命令读取当前钥匙串里证书的到期时间如果低于某个阈值直接fail提示人员先更新证书。6. 更新完成后的收尾与扩展思考证书更新完之后有几件事值得顺手做掉。一个是把所有使用该证书的工程项目里的签名配置过一遍特别是用了多个Target的项目确认每个Target都勾选或指定了新证书。另一个是TestFlight的分发配置因为TestFlight用的也是Distribution证书更新后需要重新验证一次构建。我还顺手把推送证书的更新流程写成了一个简单的检查脚本部署到推送服务器的cron里每周跑一次读取证书到期时间提前发邮件告警。脚本本身不复杂关键是把证书路径、过期时间、告警阈值这些参数化避免每次手动查。如果你的项目用到了CI/CD比如Fastlane、GitHub Actions证书更新后还需要同步更新CI环境里预存的.p12或者Apple API Key。这里有个经验值CI环境里的证书过期判断要和本地开发脱钩因为CI跑在独立的机器上它读不到你本机的钥匙串只认你配进去的认证信息。更新完本地证书后第一时间去CI的Secret配置里替换对应的证书文件不然下次自动打包又会炸一轮。最后分享一个小经验。证书过期这件事说白了就是一个定期轮换的运维问题。把流程固化下来比每次都重新摸索要节省大量时间。我第一次遇到证书过期手忙脚乱了两个小时第二次遇到用了十五分钟就完成了全部操作。这次更新我整个流程走完从后台确认到最终Archive成功花了不到十五分钟这个时间成本是完全可以接受的。希望这篇记录能帮你在下次遇到证书问题时少绕几圈弯路。
返回列表