赞
踩
CSDN 的强制 VIP 越来越恶心了,强制文章开起 VIP,本来写文章就是分享技术,后续不再在此平台更新了
macOS 中包含一项名为“门禁”的技术,旨在确保只有受信任的软件才能在 Mac 上运行,对于mac应用,我们需要进行公证才能避免App无法打开,或者是来自身份不明的开发者等等提示。
关于门禁技术 https://support.apple.com/zh-cn/HT202491
如果您的 Mac 设置为允许安装来自 App Store 和被认可开发者的应用,则第一次启动来自被认可开发者的应用时,Mac 会询问您是否确定要打开这个应用。
经过 Apple 公证的应用表示已经通过了安全检查:
没有经过公证的应用会显示一个黄色警告图标:
或者没有签名时(例如Archive
时选择Development
)直接提示
对于苹果官方 对您的 Mac 软件进行公证以在 macOS Catalina 中运行
的说明
使用Xcode 10
以上版本可以公证,如果同时安装了多个Xcode,则需要切换命令行为Xcode10
sudo xcode-select -s /path/xcode10.app
使用Archive
即可进行公证 选中xcode上方菜单->Product->Archive
然后弹出Organizer
窗口,如果不小心关掉了,这个窗口可以通过 选中xcode上方菜单->Window->Organizer
来进行打开,里面有所有的Archive记录。
选中你的macOS Apps
关于多 target 应用 archive 除开,可能不属于 iOS App, 也不属于 macOS App,变成了Other Items。
此时,设置主target 外其他target 的 Skip Install 为 YES 即可。
选择Distribute App
,选择Developer ID
方式
然后选择Upload
,即发送给苹果进行公证,而Export
则是直接导出,命令行进行公证时可以选择Export
这里如果需要选择自己的证书则使用手动Manually
,多个证书的时候但求准确
选择Upload
即可
随后弹出的界面就是让你等待公证结束,一般都很快,我几分钟就完了,公证完成后xcode会给你提示。
完成后,右下角会出现Status
为Readv to distribute
,即表示完成
点击Export Notarized App
即可以导出公证后的App
spctl -a -v xxxx.app
./TrackMix.app: accepted
source=Notarized Developer ID
./TrackMix.app: accepted
source=Developer ID
这里在我的10.13.6系统中无法验证是否Notarized
,无论怎么验证都是步骤4
,而在最新10.15的系统中验证为步骤3
,所以使用低版本mac os 验证的小伙伴不要惊慌。
spctl -v -a --type install xxx.pkg
选择右侧的Show status log
即可查看你的上传日志,如果有必要,点击“上传失败”旁边的“感叹号三角”,查看发生的错误。
这里贴出官方文档,很详细!权威嘛!
https://help.apple.com/xcode/mac/current/#/dev88332a81e
关于脚本流程官网有说明 Customizing the Notarization Workflow
但由于我使用场景的差异,在Acrhive中的配置写脚本并不符合我的使用场景,虽然很方便,如下图,值得借鉴吧,不说我还不知道有这玩意,哈哈
#! /bin/bash # Type a script or drag a script file from your workspace to insert its path. echo "####### Webcast Archive and Notarization Script / Webcast打包公证脚本 #######" #Webcast打包公证脚本 PRODUCT_NAME="Webcast" #进入当前文件路径 - 请放置在Webcast工程文件路径下 CURRENT_DIR=$(dirname $0) cd CURRENT_DIR echo "当前脚本路径为:$CURRENT_DIR" PROJECT_PATH="$CURRENT_DIR/$PRODUCT_NAME.xcodeproj" if [ ! -d $PROJECT_PATH ]; then echo "Archive and Notarization Failed : $PROJECT_PATH not exist" exit 1 fi echo "####### Webcast Archive and Notarization Script / 开始打包流程 #######" CONFIGURATION="Release" TARGET="Webcast" EXPORT_PATH="$CURRENT_DIR/Export" APP_PATH="$EXPORT_PATH/$PRODUCT_NAME.app" ZIP_PATH="$EXPORT_PATH/$PRODUCT_NAME.zip" ARCHIVE_PATH=$EXPORT_PATH/${TARGET}.xcarchive rm -r "$EXPORT_PATH" mkdir "$EXPORT_PATH" if [ -d $EXPORT_PATH ];then echo "EXPORT_PATH=$EXPORT_PATH" fi xcodebuild archive -project "$PROJECT_PATH" -scheme "Webcast" -configuration "$CONFIGURATION" -archivePath "$ARCHIVE_PATH" || { echo "Archive and Notarization Failed : xcodebuild archive action failed"; exit 1; } # 关于动态库的引用关系修改问题,使用install_name_tool指令,由于在工程中附带了脚本进行处理,这里没有写 xcodebuild -exportArchive -archivePath "$ARCHIVE_PATH" -exportOptionsPlist "$CURRENT_DIR/ExportOptions.plist" -exportPath "$EXPORT_PATH"
这里使用xcodebuild
进行acrhive和导出app包
这里需要注意的是ExportPilist
文件的设置,如果设置为upload
,是会自动进行公证的。
这里设置为export
这里的teamID就是你的证书的标识
就是钥匙串中,图中红色笔的部分啦
这里给一个示例 https://github.com/shengpeng3344/Apple-Mac-Notarized-script/blob/master/ExportOptions.plist
因为您不能直接将.app
包上传到公证服务,所以您需要创建一个包含该应用程序的压缩存档,当使用pkg
时可以不用打成zip
# 因为您不能直接将.app包上传到公证服务,所以您需要创建一个包含该应用程序的压缩存档,当使用pkg时可以忽略
ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH"
这里涉及到打包pkg的流程
这里不推荐使用packages三方工具,可以考虑使用 pkgbuild + productbuild 的命令行方式
VERSION="5.8.3"
PKGPROJ_PATH=$CURRENT_DIR/Webcast.pkgproj
# packges build command line
/usr/local/bin/packagesbuild --package-version ${VERSION} ${PKGPROJ_PATH}
FINAL_PKG="$EXPORT_PATH/${TARGET}_$VERSION.pkg"
# 需要配置你的installer证书
productsign --sign "Developer ID Installer: xxxx" $EXPORT_PATH/${TARGET}.pkg $FINAL_PKG || { echo "Archive and Notarization Failed : pkg product sign failed"; exit 1; }
# 移除旧的,未签名的pkg文件
rm $EXPORT_PATH/${TARGET}.pkg
echo "最终打包的pkg为:$FINAL_PKG"
echo "####### Webcast Archive and Notarization Script / 完成打包流程 #######"
使用xcrun altool --notarize-app
命令即可进行公证。
$ xcrun altool --notarize-app
--primary-bundle-id "com.example.ote.zip"
--username "AC_USERNAME"
--password "@keychain:AC_PASSWORD"
--asc-provider <ProviderShortname>
--file OvernightTextEditor_11.6.8.zip
echo "####### Webcast Archive and Notarization Script / 开始公证流程 #######"
xcrun altool --notarize-app --primary-bundle-id "com.xxxx.xxxx" --username "appledev@xxxx.com" --password "cgki-xxxx-xxxx-amvx" --file $FINAL_PKG
请求成功后会返回一串字符 RequestUUID
gensees-iMac-2:~ gensee$ xcrun altool --notarize-app --primary-bundle-id "com.xxx.xxxx" --username "appledev@xxxx.com" --password "cgki-xxxx-jdhu-amvx" --file /Users/gensee/Documents/SVN/uniclient/webcast/osx/Export/Webcast_5.8.3.pkg
2019-12-04 09:38:58.049 altool[50044:950440] No errors uploading '/Users/gensee/Documents/SVN/uniclient/webcast/osx/Export/Webcast_5.8.3.pkg'.
RequestUUID = b70fe4a2-689d-436d-be3e-3cf63e5276a3
上次缓存未清除
有时候我们上传一般终止,再次进行上传时,无论如何打包,clean,都无法再次上传成功了,大部分的错误信息可以通过输出的tmp文件找出原因,所以输出到文件很有必要
缓存问题删除此目录下的缓存文件即可
rm "${HOME}/Library/Caches/com.apple.amp.itmstransporter/UploadTokens/*"
注意,password
后面接的密码,并非AppleID 账号密码。需要到 https://appleid.apple.com 重生成,如下图所示
官方文档说明 https://support.apple.com/en-us/HT204397
xcrun altool --notarization-info b70fe4a2-689d-436d-be3e-3cf63e5276a3 --username "appledev@xxxx.com" --password "cgki-xxxx-xxxx-amvx"
结果如下
2019-12-04 10:03:13.863 altool[50277:971551] No errors getting notarization info.
RequestUUID: b70fe4a2-689d-436d-be3e-3cf63e5276a3
Date: 2019-12-04 01:38:58 +0000
Status: success
LogFileURL: https://osxapps-ssl.itunes.apple.com/itunes-assets/Enigma123/v4/1f/b4/8a/1fb48aa6-1abe-1294-6ce1-eeae4e54d9cc/developer_log.json?accessKey=1575619393_6818351456719557549_ixcbnih6TRyFzuQBc%2B9okeORgK%2FN01NZ3bZj%2BTrLTnCaWMERm5TF%2BG0Ccet2h7TeV36UeFwBCDpk7MshcmaxJfR8cp9uEhN1S%2FxIxdd49zZ8AR0ia%2FS6NeTMTMhy2JDWFH2hR1xEpfE0p4v0lzwWjl4oIwe%2BjNvsvMrORKy9s2Q%3D
Status Code: 0
Status Message: Package Approved
使用xcrun altool --notarization-history 0
来查看公证结果
xcrun altool --notarization-history 0 --username "appledev@xxxx.com" --password "cgki-xxxx-xxxx-amvx"
会以时间最新的排在最前,且默认为第一页。
gensees-iMac-2:~ gensee$ xcrun altool --notarization-history 0 --username "appledev@xxx.com" --password "cgki-xxxx-xxxx-amvx" Notarization History - page 0 Date RequestUUID Status Status Code Status Message ------------------------- ------------------------------------ ----------- ----------- ---------------- 2019-12-04 01:38:58 +0000 b70fe4a2-689d-436d-be3e-3cf63e5276a3 success 0 Package Approved 2019-12-03 15:09:36 +0000 eda062a8-b0c4-4db3-bd29-aadd7bdaef1e in progress 2019-12-03 13:42:16 +0000 30d82b34-c071-41bb-a351-552cecf9f1de in progress 2019-12-03 13:02:24 +0000 e153878f-8ed8-4b21-9f57-a3e6131d7a1a in progress 2019-12-03 06:41:15 +0000 96e76982-d874-45c6-9e36-868e30fb70a6 in progress 2019-12-03 02:32:50 +0000 b4d742df-2bbb-454e-81ad-18c9c57d86b5 success 0 Package Approved 2019-10-16 04:16:56 +0000 11a9ef2e-225c-49fd-a37c-73d1d00dc4d2 success 0 Package Approved 2019-10-14 11:26:28 +0000 fc4884fa-e903-45ab-b600-f4c689b9276e success 0 Package Approved 2019-10-14 10:47:22 +0000 57a7a114-a98d-40ce-beaf-b72945c9230e success 0 Package Approved Next page value: 1571050042000
公证处会生成一个票据,告诉Gatekeeper
你的应用程序已经公证处了。公证成功后,下次任何用户试图在macOS 10.14
或更高版本上运行您的应用程序时,Gatekeeper
会在网上找到票。这包括在公证前下载了你的应用程序的用户。
我们最好给包进行stapler,这样离线也可以使用。
xcrun stapler staple "Overnight TextEditor.app"
如果需要显示tiket的更多信息使用-v
xcrun stapler staple -v abc.pkg
这里我是使用sleep
方法加上while
循环,来每1min
获取下公证结果。
function uploadFileAndNotarized() { echo "start notarized $1 ..." xcrun altool --notarize-app --primary-bundle-id "com.xxxx.xxxx" --username "appledev@xxxx.com" --password "cgki-xxxx-xxxx-amvx" --file $1 &> tmp # 从日志文件中读取UUID,并隔一段时间检查一次公证结果 # 只有成功的格式是 RequestUUID = uuid=`cat tmp | grep -Eo 'RequestUUID = [[:alnum:]]{8}-([[:alnum:]]{4}-){3}[[:alnum:]]{12}' | grep -Eo '[[:alnum:]]{8}-([[:alnum:]]{4}-){3}[[:alnum:]]{12}' | sed -n "1p"` # 如果上传过了,则会返回 The upload ID is if [[ "$uuid" == "" ]];then uuid=`cat tmp | grep -Eo 'The upload ID is [[:alnum:]]{8}-([[:alnum:]]{4}-){3}[[:alnum:]]{12}' | grep -Eo '[[:alnum:]]{8}-([[:alnum:]]{4}-){3}[[:alnum:]]{12}' | sed -n "1p"` echo "The software asset has already been uploaded. The upload ID is $uuid" fi echo "notarization UUID is $uuid" # 即没有上传成功,也没有上传过,则退出 if [[ "$uuid" == "" ]]; then echo "No success no uploaded, unknown error" cat tmp | awk 'END {print}' return 1 fi while true; do echo "checking for notarization..." xcrun altool --notarization-info "$uuid" --username "appledev@xxxx.com" --password "cgki-xxxx-xxxx-amvx" &> tmp r=`cat tmp` t=`echo "$r" | grep "success"` f=`echo "$r" | grep "invalid"` if [[ "$t" != "" ]]; then echo "notarization done!" xcrun stapler staple "$1" # xcrun stapler staple "Great.dmg" echo "stapler done!" break fi if [[ "$f" != "" ]]; then echo "Failed : $r" return 1 fi echo "not finish yet, sleep 1min then check again..." sleep 60 done return 0 }
最后附上脚本,需要修改的参数有证书id
,password
以及工程名等等。
脚本下载 https://github.com/shengpeng3344/Apple-Mac-Notarized-script
对于App格式的开发包,直接压缩成zip然后进行公证即可。
spctl -v -a --type install xxx.pkg
可行的
,和证书无关,只要经过了公证即可pkg
不会提示警告,但是如果你将pkg解压,将获得的app
通过邮件分发到其他人,那么又会提示是非公证应用了,即显示感叹号,提示:无法打开"xxxxxx",因为Apple无法检查其是否包含恶意软件
。(由于我这里使用packages属于三方工具的原因?建议使用pkgbuild + productbuild 的命令行方式,我这里是做了2次公证,应该是可以优化的)对于这个说法苹果官方是这样说明的:
Important
If you distribute your software via a custom third-party installer, you need two rounds of notarization. First you notarize the installer’s payload (everything the installer will install). You then package the notarized (and stapled, as described in Staple the Ticket to Your Distribution) items into the installer and notarize it as you would any other executable. If you use a network installer, separately notarize both the installer and the items it downloads.
官方链接见这里
即需要经过两遍公证。
dmg
的开发包不需要公证,Apple的Gatekeeper
可以检测到DMG中的经过公证的.app
文件,并且可以让用户正常打开App
。
但如果里面是pkg
文件也是一样的,只要通过公证即可。
https://github.com/CaicaiNo/Apple-Mac-Notarized-scriptt
从 2023/11/01 起老的公证方式将会废除,此文所述的老版公证方式不再适用,需要使用 Mac公证脚本-Web公证方式
参考文章
macOS 开发 - Notarization 公证你的 Developer ID
应用
Customizing the Notarization Workflow
苹果官方帮助文档
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。