参考文章
对您的 Mac 软件进行公证以在 macOS Catalina 中运行
macOS 开发 - Notarization 公证你的 Developer ID 应用
关于苹果公证(Apple Notarizition)机制的一些总结
macOS app 实现自动化 notarize 脚本
Developer ID Application证书制作
准备工作:
开发者账号中,必须生成两份重要证书:
- develop ID Application 证书 —— 用来对 .app 进行分发签名。类似于 iOS 的 inhouse enterprise(企业内部分发应用)
- develop ID Installer 根证书 —— 用来对打包生成的 .dmg, .pkg 进行签名
- 一个主账号授权的副账号,用来做 .pkg / .dmg 的公正用。
这个副账号对应的专有密钥(需要在 https://appleid.apple.com 中生成) - 副账号所属的 Team ID
事件原因:
没有使用正规签名流程,或正规公证的应用,会存在如下现象:
- 经验证,对于 App,需要使用 Developer ID Application 进行签名,否则在第一次打开会提示
“身份不明的开发者”
。 - 而对于 pkg 安装包,则要使用 Developer ID Installer 进行签名,否则在安装的时候,会提示
“身份不明的开发者”
。
苹果将在 10.14.5 上新引入的 App Notarization(公证)机制,届时,苹果将要求开发人员上传应用程序之前,将它们提交给苹果,以扫描恶意内容,并查找可能存在的代码签名问题,没有经过苹果检测的应用程序以后可能将不被允许运行
- 如果没有做公正,即使使用的证书是合规证书,.pkg 安装时,Gatekeeper 机制会弹出提示 “无法打开 xxx ,因为 Apple 无法检查其是否包含恶意软件”
2020 年1月后,已安装的应用如果没有公证,也无法使用
如果是正常的应用,那么会出现
注:如果在本机上已经安装或打开过某不合规的应用,之后在一定时间内是不会再弹出提示的。
测试方法,可以尝试将不合规的应用通过 airdrop 传给另一台 Mac 进行验证。
10.14 之前的 codesign 和 productSign 不管用了
签名和公证过程
我们的流程包含两部分:app 和 pkg/dmg
1. App 签名、公证
可以通过命令行 codesign
的相关指令来完成签名。签名时务必指定 develop ID application
作为签名证书。
app 的签名和公证的步骤,建议交给 xcode 去做。公证成功后,苹果会回复一封邮件,表示我们公证通过。
这时候再去 orgonaized 里头把刚才的打包结果 export 出来
2. PKG/DMG 签名、公证
pkg/dmg 需要使用公证后的 .app 作为 source.app,然后进行打包。这里我们使用 Packages 进行打包(该第三方打包工具这里不赘述,mac 10.15 以上系统务必使用 v1.2.7 否则打包失败)
使用命令行上传公证应用
2.1 先给 pkg 文件签名
$ productsign --sign "Developer ID Installer: shu shu (428N123455)" origin.pkg signed.pkg
2.2 公证 pkg 文件
Developer ID Installer: shu shu (428N123455) 要根据实际钥匙串中的名字作相应替换。
xcrun altool --notarize-app --primary-bundle-id "app bundle id" --username "your appleid" --password "one-time-password" --file "test.pkg" -itc_provider "your team id" &> tmp
这条命令中参数较多,这里一一说明
-
--primary-bundle-id
:app 的 bundle ID -
--username
:开发者账号的 apple ID -
--password
:一次性密码,需要登录到 https://appleid.apple.com 中生成专属密钥。username 对应的也是主账号或授权的副账号 -
--file
:pkg 地址 -
-itc_provider
:副账号所属的 team ID,如果前面的 username 是主账号,那么这里不需要填这个参数
&> tmp
是将上传的内容及结果写入这个文件中。查看文件可以看到
No errors uploading './signed.pkg'.
RequestUUID = xxxxx-xxx-xxxxx-xxxxx-xxxxx
这里的 RequestUUID 通常和前面我们公证 app 时收到邮件里的内容是一致的。
2.3 进行盖章
公证成功后,会返回一个 ticket 用于 staple(盖章),执行下面的命令进行盖章。
xcrun stapler staple signed.pkg
2.4 验证 .app, .pkg/.dmg 是否有效
# App
spctl -a -v --type exec ./test.app
# pkg
spctl -a -v --type install ./test\_sign.pkg
查询结果:
spctl -a -v --type install abc.pkg
#公证后的
/xxx/abc.pkg: accepted
source=Notarized Developer ID
#没公证的
/xxx/abc.pkg: rejected
source=Unnotarized Developer ID
未解之谜
- 实际发现有些情况会显示 reject, source=Notarized Developer ID, 并且可以正常安装,不会报错。
- 我将一个公证的和未公证的 app 一起打包入一个 pkg. pkg 正常签名,公证,但是盖章会失败(RequestUUID 不相同)。理论上这个 pkg 应该是会被列为无效,但实际测试发现不会弹出“未知应用”或“恶意软件”的提示。
长命令示例:
xcrun altool --notarize-app --primary-bundle-id "com.XXX.XXXX.XXXX" --username "xxxxxx@qq.com" --password "xxxx-xxxx-xxxxx-xxxx" --file ./signed.pkg -itc_provider "XXXXXXXXX" &>tmp
这条命令中参数较多,这里一一说明
-
--primary-bundle-id
: 包名,bundle ID -
--username
:apple ID -
--password
:https://appleid.apple.com 去这里生成吧 -
--file
:pkg 地址 -
-itc_provider
:team ID 开发团队的 ID