MacOS 签名+公证 APP"/>
MacOS 签名+公证 APP
背景
在MacOS 10.15之前,应用如果没有签名,那么首次打开时就会弹出这种“恶意软件”的提示框。这时只要应用签名了,就不会弹这个框。但在MacOS 10.14.5之后,应用如果没有公证(简单说就是将安装包上传到Apple审查),那么就会弹出更严重的“恶意软件”提示框。
准备
- 必须要有开发者账号
- 通过开发者账号生成签名证书。此处需要注意,如果不仅仅是签名APP,还想签名安装包的话,需要两个证书(Developer ID Application/Developer ID Installer)。在创建证书时,需要注意勾选必要的扩展服务。
- 将证书安装在打包的Mac上
签名
步骤一:为APP签名
codesign --force --sign "$SIGNING_IDENTITY" --entitlements="$ENTITLEMENTS" --options=runtime "$APP_PATH"
变量说明:
- SIGNING_IDENTITY:证书名称,示例:Developer ID Application: xxxx (ABCDEFGHIJ)。
- ENTITLEMENTS:用于定义应用程序的权限和特权,示例:xxxx.entitlements。
- APP_PATH:APP所在路径
验证签名:
codesign --verify --verbose "$APP_PATH"
步骤二:打包APP
pkgbuild --component "$APP_PATH" --identifier "$IDENTIFIER" --version 6.0 --install-location /Applications "$COMPONENT_PKG_PATH"
变量说明:
- APP_PATH:APP所在路径
- IDENTIFIER:APP的identifier,在APP的Info.plist文件中有该字段,用开发者账号创建自己的APP时可定义。
- COMPONENT_PKG_PATH:安装包存放目录
此处用 productbuild 亦可。我自己的理解是 pkgbuild 打包的是组件安装包,productbuild 是用来打包产品安装包 。一个安装包可能会有多个组件构成,但是我的 app 安装包只有一个组件,所以 pkgbuild 和 productbuild 都可。
当时为了赶任务进度,并没有多考虑,就又用 productbuild 打了下 pkgbuild 的输出物。
productbuild --package "$COMPONENT_PKG_PATH" "$PRODUCT_PKG_PATH"
步骤三:签名pkg
productsign --sign "$INSTALLER_IDENTITY" "$PRODUCT_PKG_PATH" "$PRODUCT_SIGN_PKG_PATH"
变量说明:
- INSTALLER_IDENTITY:证书名称,示例:Developer ID Installer: xxxx (ABCDEFGHIJ)。
- PRODUCT_PKG_PATH:产品安装包路径。
- PRODUCT_SIGN_PKG_PATH:完成签名后的产品安装包存放位置。
验证签名:
pkgutil --check-signature "$PRODUCT_SIGN_PKG_PATH"
公证
altool:使用的旧的 Apple Notary Service,适用于 Xcode 12 以及更早的版本,但是需要注意的是Apple 将会在 2023 年秋季停止对它的支持。
xcrun notarytool store-credentials "123123123" --apple-id "xxxxxx@xxxxxx" --team-id "ABCDEFGHIJ" --password "XXXX-XXXX-XXXX-XXXX"
xcrun notarytool submit "$PRODUCT_SIGN_PKG_PATH" --keychain-profile "123123123" --wait
参数和变量说明:
- store-credentials: 存储凭证,这个随便输入,但是一定要记住。
- apple-id:开发者账号。
- team-id:组ID,就是证书名称()中的内容。
- password:应用专属密码,用开发者账号生成,生成完毕一定要记住。
- PRODUCT_SIGN_PKG_PATH:产品安装包路径。
- keychain-profile:存储凭证(就是之前随便输入的)。
- wait:这个参数是等公证结束反馈结果,猜的,没验证。
装订票据
xcrun stapler staple "$PRODUCT_SIGN_PKG_PATH"
我看苹果官网文档时,自己把它翻译成装订票据,可能译过来并不准确。这个命令的作用是用于向已签名的应用程序或安装包(PKG 文件)添加 "ticket",以标记该应用程序或安装包已被"stapled"。Stapler 是 Apple 提供的一个工具,用于支持应用程序的安全性和分发验证。"staple" 的作用是将一个由 Apple 颁发的 "ticket" 绑定到应用程序或安装包中,证明该应用程序或安装包已经经过苹果的公证和验证。这样,用户在下载和安装应用程序时,系统会自动检查该 "ticket",确认应用程序已经被签名和公证,从而增加用户对应用程序的信任。
FAQ:
很少人会先看完文档再动手,你们可能会在过程中遇到好多坑。
- 签名失败。确保证书相应的扩展服务是否开启,比如说:代码签名。安装包不需要这个扩展服务。其次就是,MacOS是否放开了对证书的访问权限。打开“钥匙串访问”-“系统”-“我的证书”:点开证书前的>,然后查看密钥详情,访问控制改为“允许所有应用程序访问此项目”。
- 公证失败。根据公证反馈的UUID来查看错误日志。苹果官方会根据错误给出解决方法。
列出我遇到的问题:xcrun notarytool log "UUID" --keychain-profile "123123123"
- 可执行程序签名时未进行强制运行时:在app签名后,单独再签名这个可执行程序,并 加上参数"--options=runtime"。
codesign --force --sign "$SIGNING_IDENTITY" --options=runtime $APP_PATH/Contents/MonoBundle/createdump
- 第三方库未签名,单独对这些第三方库进行签名即可。
find "$APP_PATH/Contents/MonoBundle" | while read -r MonoBundle_Files_Name; doif [[ -f "$MonoBundle_Files_Name" && "${MonoBundle_Files_Name##*.}" = "dylib" ]];thenecho "[INFO] Signing $MonoBundle_Files_Name"codesign --force --sign "$SIGNING_IDENTITY" "$MonoBundle_Files_Name"fidone
- 可执行程序签名时未进行强制运行时:在app签名后,单独再签名这个可执行程序,并 加上参数"--options=runtime"。
- 公证成功后,安装程序安装成功,但是APP运行崩溃。可能是codesign的entitlements参数指定的权限文件内容缺少。这可能是强化运行时带来的问题,此处推荐官方链接:强化运行时 |苹果开发者文档 (apple)
更多推荐
MacOS 签名+公证 APP
发布评论