注册了 Apple Developer 账号之后,打出来的包用户下载会被 Gatekeeper 拦截,提示「
无法验证开发者」。要让所有用户都能正常打开,需要完成两件事:Developer ID
Application 证书签名
+ Apple 公证(Notarization)

本文记录了从零开始配置的完整过程,以及中间遇到的各种报错。


概念梳理

概念 说明
Developer ID Application 用于在 Mac App Store 以外分发 App 的证书
Ad-hoc 签名 - 号签名,仅本机可用,无法通过 Gatekeeper
公证(Notarization) 将 App 提交 Apple 服务器扫描,通过后颁发票据
Staple 将公证票据嵌入 DMG/App,用户离线也能验证

第一步:生成 CSR 并创建证书

关键顺序:先在本机生成 CSR,再去 Apple 后台创建证书

常见错误是先在 Apple Developer 后台点创建,再下载 .cer 安装。这样本机没有对
应私钥,证书装不进去。

打开钥匙串访问 → 菜单栏 → 证书助理 → 从证书颁发机构请求证书

  • 用户电子邮件地址:Apple ID 邮箱
  • 常用名称:随意,如 MyApp Developer
  • 选择:存储到磁盘

保存生成的 CertificateSigningRequest.certSigningRequest 文件。

在 Apple Developer 后台创建证书

  1. 登录
    developer.apple.com
  2. 点击 Certificates → +
  3. 选择 Developer ID Application
  4. Profile Type 选 G2 Sub-CA (Xcode 11.4.1 or later)
  5. 上传上一步生成的 CSR 文件
  6. 下载 .cer 文件

安装证书

open ~/Downloads/developerID_application.cer

钥匙串访问弹窗点添加

验证安装

security find-identity -v -p codesigning | grep "Developer ID"

正常输出:

1) ABCDEF1234... "Developer ID Application: Your Name (TEAMID)"

第二步:创建 App-Specific Password

公证时不能直接用 Apple ID 密码,需要单独生成一个。

  1. 登录 appleid.apple.com
  2. Sign-In and Security → App-Specific Passwords → Generate
  3. 名字随意,如 myapp-notarize,保存生成的密码(格式 xxxx-xxxx-xxxx-xxxx

第三步:配置本地环境变量

在项目根目录创建 .env.local,加入 .gitignore 不提交:

APPLE_SIGNING_IDENTITY=Developer ID Application: Your Name (TEAMID)
[email protected]
APPLE_PASSWORD=xxxx-xxxx-xxxx-xxxx
APPLE_TEAM_ID=XXXXXXXXXX

Team ID 就是 security find-identity 输出中括号里的字符串。

安全加载方式(避免 xargs 空格问题,见踩坑三)

if [ -f ".env.local" ]; then
while IFS='=' read -r key value; do
[[ "$key" =~ ^#.*$ || -z "$key" ]] && continue
key="${key// /}"
value="${value#"${value%%[![:space:]]*}"}"
value="${value%"${value##*[![:space:]]}"}"
export "$key=$value"
done < .env.local
fi

第四步:Tauri 项目配置

tauri.conf.json 中将 signingIdentity 设为 null,Tauri 会自动读取环境变量
APPLE_SIGNING_IDENTITY

"bundle": {
"macOS": {
"signingIdentity": null
}
}

第五步:构建、公证、Staple

# 构建(Tauri 自动签名)
npm run tauri build -- --target universal-apple-darwin

# 公证(约 1-3 分钟)
xcrun notarytool submit MyApp.dmg \
--apple-id "$APPLE_ID" \
--password "$APPLE_PASSWORD" \
--team-id "$APPLE_TEAM_ID" \
--wait

# 钉附票据到 DMG
xcrun stapler staple MyApp.dmg

# 验证
xcrun stapler validate MyApp.dmg

验证公证结果

spctl --assess --type open --context context:primary-signature -v MyApp.dmg
# MyApp.dmg: accepted
# source=Notarized Developer ID

输出 source=Notarized Developer ID 表示公证成功,用户下载后 Gatekeeper 自动放
行。


踩坑记录

踩坑一:Error -25294,证书无法导入

An error occurred. Unable to import "Developer ID Application: ..."
Error: -25294

原因:先在 Apple Developer 后台创建并下载了证书,本机没有对应的私钥。

解决:在 Apple Developer 后台 Revoke 旧证书,重新按「先生成 CSR → 再创建证书
」的顺序操作。


踩坑二:unable to build chain / errSecInternalComponent

Warning: unable to build chain to self-signed root for signer "..."
errSecInternalComponent
failed to sign app

原因:Apple 的中间证书(WWDR G2 Intermediate CA)没有安装,证书链不完整。

解决

curl -O https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer
sudo security add-certificates -k /Library/Keychains/System.keychain DeveloperIDG2CA.cer

也可以在钥匙串访问中手动导入:文件 → 导入项目 → 选择 .cer 文件 → 选目标钥
匙串为系统


踩坑三:CSSMERR_TP_NOT_TRUSTED,valid identities 为 0

1) XXXX "Developer ID Application: ..." (CSSMERR_TP_NOT_TRUSTED)
0 valid identities found

原因:同踩坑二,中间证书缺失导致信任链断开。security find-identity -v 只显
示 valid 证书,因此结果为 0,签名命令找不到可用身份。

解决:安装 WWDR G2 中间证书(同踩坑二)。


踩坑四:.env.local 含空格的值被截断

./deploy.sh: line 11: export: `Application:': not a valid identifier
./deploy.sh: line 11: export: `(TEAMID)': not a valid identifier

原因export $(grep -v '^#' .env.local | xargs)xargs 会按空格分割
Developer ID Application: ... 被拆成多个 token。

解决:改用第三步中的 while IFS='=' read 方式加载,可正确处理值中的空格。


踩坑五:签名身份末尾有隐藏空格

"Developer ID Application: Your Name (TEAMID)                        ": no identity found

原因:从终端复制 security find-identity 输出时,行末带了大量空格,粘贴进
.env.local 后一起保存了。

解决

# 清除文件所有行末空格
sed -i '' 's/[[:space:]]*$//' .env.local

踩坑六:Xcode 项目找不到 Mac Development 证书

No signing certificate "Mac Development" found:
No "Mac Development" signing certificate matching team ID "..." found.

原因CODE_SIGN_STYLE=Automaticxcodebuild archive 时默认寻找开发证书
(Mac Development),但我们只有分发证书(Developer ID Application)。

解决:手动指定 Manual 签名模式和 Developer ID:

xcodebuild -project MyApp.xcodeproj \
-scheme MyApp \
-configuration Release \
-archivePath ./build/MyApp.xcarchive \
archive \
CODE_SIGN_STYLE=Manual \
CODE_SIGN_IDENTITY="Developer ID Application" \
DEVELOPMENT_TEAM="YOUR_TEAM_ID" \
OTHER_CODE_SIGN_FLAGS="--timestamp"

.gitignore 补充

证书相关文件不应提交到仓库:

*.cer
*.p12
*.p8
*.mobileprovision
*.provisionprofile
.env.local