苹果代码签名分为两大场景:Mac App Store 上架、独立分发(官网下载);两种都需要付费 Apple Developer 账号($99 / 年),免费 ID 仅能本地调试,无法对外分发。 完整流程:证书准备 → Xcode 可视化签名 / 命令行 codesign 手动签名 → 公证 Notarize(独立分发必做) → Staple 装订票据。
登录 Apple Developer 开通年度开发者计划。
进入「Certificates, IDs & Profiles」创建证书,先通过钥匙串生成 CSR 请求文件上传: 表格
| 证书类型 | 用途 | 分发渠道 |
|---|---|---|
| Apple Distribution | 签名.app,上架 Mac App Store | App Store |
| Developer ID Application | 签名.app、二进制、框架 | 官网独立分发 |
| Developer ID Installer | 签名.pkg 安装包 | 独立分发安装包 |
下载.cer证书文件,双击导入「钥匙串访问 - 登录」;
导出.p12备份(带密码,CI / 换电脑必备);
查看本机可用签名身份:
bash运行
security find-identity -v -p codesigning
输出示例:1) "Developer ID Application: 公司名 (团队ID)",引号内字符串为签名标识。
适合 Swift/Objective-C 原生 macOS 项目,全自动处理嵌套框架、插件、权限:
打开项目 → 选中左侧项目名 → Signing & Capabilities;
勾选 Automatically manage signing,选择你的开发者 Team;
开启 Hardened Runtime(硬化运行时)(独立分发强制要求);
按需添加权限 Entitlements(文件读写、网络、JIT 等);
打包分发:
顶部菜单 Product → Archive 生成归档包;
打开 Window → Organizer → Archives,选中归档包点击 Distribute App;
独立分发选 Developer ID,勾选「Upload to Apple notary service」自动上传公证;
公证完成后导出带公证票据的.app文件Apple Developer。
Xcode自动签名配置
归档分发公证界面
先签内嵌工具、动态库、Framework、插件,最后签外层.app主程序,否则签名失败Apple Developer。
bash运行
codesign --force # 强制覆盖旧签名 --deep # 递归签名所有内嵌文件 --sign "Developer ID Application: 你的公司 (团队ID)" --options runtime # 开启硬化运行时(强制) --timestamp # 苹果时间戳,防证书过期失效 --entitlements entitlements.plist # 权限配置文件 ./你的程序.app
--options runtime:macOS 10.15 + 强制,不开启无法通过公证;
--timestamp:必须加,否则证书过期后软件直接打不开;
entitlements.plist:权限配置,无特殊权限可省略。
xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.cs.allow-jit</key> <true/> <key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/> <key>com.apple.security.cs.disable-library-validation</key> <true/> </dict> </plist>
bash运行
# 基础校验 codesign --verify --deep --strict ./你的程序.app # 查看完整签名信息 codesign -d -vv ./你的程序.app
无报错即签名合法。
打包 pkg 后使用productsign签名:bash运行
productsign --sign "Developer ID Installer: 公司名(团队ID)" 未签名.pkg 输出签名后.pkg
仅签名不公证,用户打开会弹出「无法验证开发者」恶意软件拦截弹窗。
登录 appleid.apple.com → 安全 → 生成应用专用密码(16 位,不能用账号主密码);
钥匙串存储公证凭证(只需执行一次):
bash运行
xcrun notarytool store-credentials "公证凭证名" --apple-id "你的开发者邮箱" --team-id "你的TeamID" --password "16位应用专用密码"
bash运行
# 先把app打包zip ditto -c -k --keepParent ./你的程序.app app.zip # 提交并等待结果 xcrun notarytool submit app.zip --keychain-profile "公证凭证名" --wait
输出status: Accepted代表公证成功。
把苹果公证凭证嵌入程序,用户断网也能通过 Gatekeeper 校验:bash运行
# 给app装订 xcrun stapler staple ./你的程序.app # 给pkg/dmg装订同理 xcrun stapler staple 安装包.pkg
bash运行
spctl --assess --verbose --type execute ./你的程序.app
输出accepted即完全合规,可以对外分发。
导出证书.p12,存入仓库密钥;
构建脚本导入证书到临时钥匙串:
bash运行
security create-keychain -p ci temp.keychain security import cert.p12 -k temp.keychain -P 证书密码 -T /usr/bin/codesign security default-keychain -s temp.keychain
执行上述 codesign、notarytool 自动化流程。
无开发者账号可本地生成自签名证书,仅用于内部调试,外部 Mac 打开仍会拦截:
打开「钥匙串访问 → 证书助理 → 创建证书」;
类型Self Signed Root,用途Code Signing;
用codesign -s "证书名" ./程序.app签名,无法公证Apple Developer。
创建自签名证书界面
no identity found:证书未导入钥匙串、证书类型选错;
signature invalid:未按从内到外顺序签名、缺少--deep;
公证失败:忘记--options runtime、权限 plist 缺失、bundle id 不匹配;
Gatekeeper 拦截:完成公证 + staple 装订,或右键「打开」一次绕过临时校验。