ITMS-90034 签名缺失或无效:修复方法
作者:Mehdi Azizi
发布于 ,8分钟
ITMS-90034 表示你的 build 没有用有效的分发证书签名。先用 codesign 查看签名,再用 EAS 重新构建 store build。
ITMS-90034 出现在你把 build 上传到 App Store Connect 的时候。它的意思是:你的 app,或者其中某个组件,没有用 Apple 提交证书签名,也就是没有用有效的分发证书。解决办法:找出是哪个 bundle 签错了、为什么签错,然后重新构建一个用于 App Store 的签名 build。
这篇指南只讲这个错误。如果你对证书和描述文件这些概念还比较模糊,先读 iOS 开发者证书和 provisioning profile。这里你会看到:要读的报错信息、一棵决策树、检查 IPA 的命令,以及用 EAS 托管凭据的修复方法。EAS 这部分,我读过 EAS CLI 24.10.0 里选择证书的代码。
ITMS-90034 错误是什么意思?
它的典型形式如下(名称是示例):
ITMS-90034: Missing or invalid signature. The bundle 'com.example.myapp' at bundle path 'Payload/MyApp.app' is not signed using an Apple submission certificate.
2026 年,在 Apple 论坛上,它也会以 "Validation failed (409) Missing or invalid signature" 的形式出现,后面跟着同样的文字和 "(ID: 90034)"。
所谓"提交证书",就是分发证书。Apple 关于证书的帮助文档写得很清楚:开发证书用来在你自己的设备上运行 app,分发证书用来分发 app 或上传到 App Store Connect。
看报错里引用的路径:它指出了出问题的 bundle。 Payload/MyApp.app 指的是 app 本身。以 .appex 结尾的路径指的是扩展,比如小组件。以 .framework 结尾的路径指的是内嵌的库。
这不是审核员的拒绝。校验发生在上传时或 build 处理过程中,在 TestFlight 之前:这个 build 永远到不了你的测试人员手里。
决策树:从报错到修复
每一行对应一个线索,你可以在报错信息、下一节的命令或 EAS 日志里看到。按顺序看:第一条对上的就是你的方向。
| 你看到的现象 | 可能原因 | 修复方法 |
|---|---|---|
路径以 .appex 结尾 | 扩展签名错误 | 声明该扩展 |
Signature=adhoc | build 未签名 | 用 store 配置构建 |
Apple Development | 开发 build | 用 store 配置构建 |
读到 ProvisionedDevices | 内部 build(ad hoc) | 用 store 配置构建 |
sealed resource | IPA 构建后被改动 | 重新构建 |
| EAS:"no longer valid" | 证书已被吊销 | 新建证书 |
| 一切都有效 | Apple 那边的故障 | 重新上传,再反馈 |
用四条命令检查你的 IPA
从 expo.dev 上该 build 的页面下载 IPA,然后在你的 Mac 上打开终端。
1. 是谁签的这个 app?
unzip -q MyApp.ipa -d ipa
codesign -dv --verbose=4 ipa/Payload/*.app 2>&1 | grep -E "^(Identifier|Authority|Signature|TeamIdentifier)="
codesign 输出到标准错误,所以要加 2>&1。根据 Apple 技术说明 TN3161,每一行 Authority 都是信任链中的一环。第一行应该以 Apple Distribution: 或 iPhone Distribution: 开头,后面是你团队的名称。第二种写法是旧的 iOS Distribution 类型:从代码来看,EAS CLI 24.10.0 仍然会创建这种类型的证书。如果你看到 Apple Development:,那就是开发 build。如果你看到 Signature=adhoc 而且没有任何 Authority 行,说明这个二进制没有被任何证书签名。
2. app 签名之后被改过吗?
codesign --verify --deep --strict -vv ipa/Payload/*.app
你希望看到 valid on disk,然后是 satisfies its Designated Requirement。TN3161 说明了这项检查保证什么:所有预期的文件都在,没有新增文件,也没有文件被修改。我拿一个测试 bundle 签名后再改动,这条命令返回 a sealed resource is missing or invalid,接着是 file modified: 加上被改的文件。这里的 --deep 选项只用来校验,绝不要用来签名:在 Apple 论坛上,一位技术支持团队的工程师就不建议用它签名。
3. 内嵌的是哪个描述文件?
security cms -D -i ipa/Payload/*.app/embedded.mobileprovision -o profil.plist
plutil -extract ProvisionedDevices xml1 -o - profil.plist
plutil -extract ExpirationDate raw profil.plist
这些命令来自 关于描述文件的技术说明 TN3125。App Store 描述文件不包含任何设备列表:第二行应该返回 Could not extract value。如果它显示了设备标识符,那就是 ad hoc 描述文件,也就是内部 build 用的。第三行给出描述文件的过期日期。
4. 扩展和框架的签名一致吗?
find ipa/Payload/*.app \( -name "*.appex" -o -name "*.framework" \) \
-exec sh -c 'echo "$1"; codesign -dvv "$1" 2>&1 | grep -m1 "^Authority="' _ {} \;
每个组件都应该显示和 app 相同的 Authority 行。哪个不一样,报错里提到的就是它。
如果你想在上传前检查,TN3161 推荐用 altool,它和 Xcode 里 Validate App 按钮做的是同一项检查。它需要一个 App Store Connect API 密钥,密钥文件 AuthKey_<KEY_ID>.p8 要放在 ~/.appstoreconnect/private_keys 里:
xcrun altool --validate-app -f MyApp.ipa -t ios --api-key <KEY_ID> --api-issuer <ISSUER_ID>
用 EAS 逐个原因修复
把内部 build 或开发 build 传给了 Apple
根据 Expo 关于 eas.json 的文档,"distribution": "internal" 的 build 不是为商店签名的:它们用的是 ad hoc 描述文件。只有分发方式为 store(默认值)的配置才能生成可上传的 build。最稳妥的做法是直接上传你刚构建好的 build,不要手动去挑:
eas build --platform ios --profile production --auto-submit
如果你用 eas submit --path,确认这个文件确实是你最新的 store build。在 Apple 论坛上,有个团队发现他们的上传工具每次都传了一个放在 git 里的旧 IPA。
漏掉了某个扩展
每个扩展都是独立的 bundle,有自己的标识符和自己的描述文件。在使用原生代码生成的 Expo 项目里,Expo 关于 iOS 扩展的页面要求在 extra.eas.build.experimental.ios.appExtensions 中声明它们。这样 EAS CLI 在构建前就知道它们,并会创建或校验它们的凭据。大多数会添加扩展的库都会通过自己的插件帮你写好这段声明。
Solys 是我做的小游戏闹钟,里面有四个扩展:一个小组件和三个 Screen Time(屏幕使用时间)扩展。四个都在配置里声明了,EAS 为每个都准备了描述文件。如果某个扩展是在 Xcode 里手动加的,没有做这个声明,那它就是报错里出现 .appex 路径的头号嫌疑。
证书被吊销或已过期
Apple 关于证书的页面说得很明确:用过期或被吊销的证书签名的 build 不能再上传。一个已经上传但还没提交审核的 build,如果它的证书被吊销,甚至可能变成 Invalid Binary 状态。
EAS CLI 24.10.0 的代码显示了这种情况什么时候会被漏掉:
- 交互式构建,已连接 Apple:EAS 会把它的证书和 Apple 那边仍然有效的证书对比。如果对不上,它会显示 "Current distribution certificate is no longer valid in Apple Dev Portal",并让你选择或新建一个。
- 交互式构建,未连接:EAS 只检查日期,并提示它跳过了 Apple 端的校验。
- 非交互式构建,在持续集成中:EAS 显示 "Distribution Certificate is not validated for non-interactive builds",然后照样签名。
在持续集成里,EAS 不会再次校验证书本身:证书被吊销可能要到上传时才暴露。 解决方法:运行一次连接你 Apple 账号的交互式构建,或者用 eas credentials --platform ios,进入 Build Credentials 菜单,再选 "Distribution Certificate: Add a new one to your account"。包含旧证书的描述文件会失效:EAS 会在下一次构建时检查并重新生成它们。Apple 对证书数量的限制,详见 iOS 开发者证书指南。
二进制在签名后被修改
签名通过哈希值把代码、资源和元数据封存起来,Apple 技术说明 TN3126 有详细解释。解压 IPA 改一个文件再重新压缩,就会破坏这个封印。在你的配置里做修改,然后重新构建。 永远不要手动改 EAS 生成的 IPA。
代码放错位置也是同样的道理,比如放在 .zip 压缩包里:App Store 无法对它重新签名。Apple 在关于 bundle 内容的页面里说明了允许的位置。
本地凭据
如果你的 EAS 配置用了 "credentialsSource": "local",你的 credentials.json 文件会指向一个 .p12 证书和一个 .mobileprovision 描述文件。用第 3 步的命令检查描述文件:它必须是 App Store 类型,并且包含你当前的分发证书。另外,这些文件不要放进代码仓库,和 Expo app 的 API 密钥一样。
一切都有效的时候
还剩一种让人头疼的情况。在 Apple 论坛上,有开发者什么都没改,重新上传同一个 build,错误就消失了。2026 年 8 月和 9 月,有两个帖子描述了相反的情况:证书和描述文件都是新的,签名也验证过,还是一直失败。其中一个帖子里,一位 Apple 工程师建议提交 bug 报告,附上 IPA、签名分析和 Transporter 日志,然后联系 App Store Connect。
所以,先用新的 build 号重新上传一次。如果你的四条命令结果都没问题,错误还是出现,就带着这些材料向 Apple 反馈。不要条件反射地去吊销证书:这解决不了任何问题,还会让你的描述文件失效。
上传 build 不再踩坑
签名在上传前两分钟就能检查完。其他自动检查也需要同样严谨,比如 Xcode 版本相关的 ITMS-90725,或者权限说明文字相关的 ITMS-90683。从构建到上传、不用 Mac 的完整流程,见 不用 Mac 发布 iOS app。
审核员的拒绝需要更冷静地处理:应对方法在 app 被 Apple 拒绝这一页,最常见的拒绝原因在 Apple 为什么拒绝你的 app。
想在上传前检查你的材料,Review Kit 里有我的检查清单,还有会帮你审查项目的 Claude Code skills。如果你的上传卡住了,想找个人帮你看看,和我预约一小时:我们视频通话,在你的屏幕上一起过你的项目。如果你正在准备第一次发布,做一下免费诊断:它会帮你理顺步骤顺序,并把我的防 Apple 拒审清单发给你。
常见问题
ITMS-90034 是 App Review 的拒绝吗?
不是。这是上传 build 时的自动校验,发生在 TestFlight 之前,也在任何审核之前。没有人打开过你的 app:Apple 只是发现它的签名不是来自有效的分发证书。
修复 ITMS-90034 需要吊销我的分发证书吗?
只有在证书泄露或已经失效时才需要。吊销一个正常工作的证书会让你的描述文件失效,却不能解决根本原因。先用 codesign 查看 IPA 的签名,然后按决策树指出的问题去修。
能用远程更新修复 ITMS-90034 吗?
不能。签名是二进制的一部分,被拒的 build 永远无法使用。你必须生成一个正确签名的新二进制并重新上传。
为什么报错提到的是我的小组件,而不是我的 app?
因为小组件是独立的 bundle,用自己的描述文件签名。如果它没有向 EAS 声明,或者用别的方式签了名,整个上传都会失败。在配置里声明这个扩展,然后重新构建。
如果 codesign 显示一切有效怎么办?
再检查一下内嵌的描述文件和每个扩展。如果都没问题,用新的 build 号重新上传一次。如果错误还在,就向 Apple 提交报告,附上 IPA、codesign 的输出和上传日志。

