查看、验证和创建 macOS 代码签名,是 Gatekeeper 信任链的起点。
codesign 用钥匙串中的签名身份为 app、framework、插件和安装包签名,并在产物里写入签名、 entitlements 和时间戳。-s 指定身份,--options runtime 启用硬化运行时,--timestamp 请求可信时间戳,--entitlements 附加权限声明。签名必须由内向外:先签嵌套的 framework、XPC 服务和辅助工具,再签外层 app。
边界:签名只证明“是谁签的、内容有没有被改”,要过 Gatekeeper 还必须有有效的 Developer ID 证书和私钥、启用硬化运行时、完成 Apple 公证(notarization)并 stapling。钥匙串未解锁、私钥 ACL 未放行时,签名会失败或弹窗卡住。临时改动用 ad-hoc 签名(-s -)只能在本地测试,不能分发。
# 1. 查看现有签名、Team ID、flags 和时间戳;信息写在 stderr
% codesign --display --verbose=4 /Applications/Safari.app 2>&1 | head -20
# 2. 验证签名完整性和嵌套代码
% codesign --verify --deep --strict --verbose=2 MyApp.app
# 3. 导出 entitlements,确认应用申请了哪些权限
% codesign -d --entitlements :- MyApp.app 2>/dev/null
# 4. 用 Developer ID 身份签名,启用硬化运行时并加时间戳
% codesign -s "Developer ID Application: Example Corp (TEAMID1234)" \
--options runtime --timestamp --entitlements MyApp.entitlements -f MyApp.app
# 5. 用 Gatekeeper 的评估逻辑检查能否放行
% spctl --assess --type execute -vv MyApp.app
# 6. 公证并等待结果,再 stapling 到 app 上供离线校验
# 先执行 xcrun notarytool store-credentials AC_PASSWORD 保存凭据
% xcrun notarytool submit MyApp.zip --keychain-profile "AC_PASSWORD" --wait
% xcrun stapler staple MyApp.app
% xcrun stapler validate MyApp.app
--deep 给整个 app 签名并不可靠:Apple 不推荐用它代替逐个签名嵌套代码;应先签 framework、插件、辅助工具,再由内向外签主 app,顺序反了会让外层签名立即失效。--options runtime 或 --timestamp,公证会拒绝;codesign -dv 的 flags 里应能看到 runtime 和 timestamp。security 的 unlock-keychain 与 set-key-partition-list。codesign -dv 看起来“没输出”:它把详情写到 stderr,脚本要 2>&1;用 --verify 的退出码判断是否通过。xattr -d com.apple.quarantine 只适合本地测试,不是分发方案。security — 钥匙串、证书和签名身份的前置配置。csrutil — SIP 对系统二进制和调试的限制。sudo — 系统级安装与权限。openssl — 对照证书链与签名验证。合上页面,先回答,再展开对照。
codesign 签名,为什么应用仍可能被 Gatekeeper 拦截?codesign -dv 看不到输出、codesign --verify 又失败时,应该怀疑什么?-dv 把信息写到 stderr,需要重定向;同时检查钥匙串是否解锁、身份是否存在、嵌套代码是否都已正确签名。
小程序版
微信扫码,随时查命令