Notarize a Command Line Tool
经过初浅的Google 翻译:
macOS 10.15 Catalina 要求 应用程序和工具 需要经过公证。
Developer ID Certificates
要在App Store之外分发二进制文件(应用程序和命令行工具),您需要“开发者ID应用程序”证书。要签署安装程序包以在Mac App Store之外分发,您需要提供“开发人员ID安装程序”证书。
如果尚未创建它们,则可以在Xcode或Developer Portal中进行。如果您已经拥有证书,但在另一台Mac上,则需要导出它们,然后在新Mac上重新导入它们。创建新证书可能会使现有证书无效! 所以要当心。
在工作计算机上创建或导入证书后,您可以使用以下方法在终端中验证证书的存在:
$ security find-identity -p basic -v
此命令将列出此Mac上的所有可用证书。检查您是否可以看到“开发人员ID应用程序”和“开发人员ID安装程序”证书。如果您是多个团队的成员,则每个团队可能会看到多个证书。
您以后可以通过长十六进制数字或描述性名称来标识证书(或“身份”),例如 "Developer ID Installer: Armin Briegel (ABCD123456)"
名称末尾的十个字符代码是您的开发人员团队ID。记下它。如果您是多个开发人员团队的成员,则可以拥有多个开发人员ID证书,团队ID将帮助您区分它们。
您的开发者帐户的应用专用密码
Apple要求使用两因素身份验证保护开发者帐户。要允许需要身份验证的自动化工作流,您可以创建应用程序特定的密码。
在Apple ID门户中为您的开发人员帐户创建一个新的应用程序专用密码。
- Apple支持:使用应用专用密码
创建密码时,只会显示密码。立即在您的钥匙串中使用以下字段创建“新密码项”:
- 钥匙扣物品名称: Developer-altool
- 帐户名称:您的开发者帐户电子邮件
- 密码:您刚创建的应用专用密码
这将创建一个开发人员专用的密码项目,我们可以从工具中安全地访问该项目。
如果需要,您还可以将应用程序特定的密码存储在其他密码管理器中,但是Xcode工具具有使用“钥匙串”的特殊选项。
启用强化运行时
启用“ Hardened Runtime”将以某种方式编译二进制文件,从而使外部进程更难以注入代码。从2020年1月开始,这是成功进行公证的要求。
- 在更改签名选项的视图中,单击上方选项卡行中的“构建设置”
- 单击“全部”以显示所有可用设置
- 在搜索字段中输入“ enable hardened”,这将显示“ Enable Hardened Runtime”设置
- 将项目列(蓝色图标)中的值设置为
YES
建立pkg
命令行工具可以签名,但不能直接公证。但是,您可以对包含命令行工具的zip,dmg或pkg文件进行公证。同样,当您的工具带有正确的安装包时,对于用户和管理员来说,安装起来也容易得多。
我们可以使用pkgroot目录作为有效负载来构建安装程序包:
pkgbuild --root build/pkgroot \
--identifier "com.example.hello" \
--version "1.0" \
--install-location "/" \
--sign "Developer ID Installer: Armin Briegel (ABCD123456)" \
build/hello-1.0.pkg
为了清楚起见,我将命令分为多行,您可以在一行中输入该命令,而无需使用行尾反斜杠\。您想用数据替换标识符,版本和签名证书的值。
对安装程序包进行公证
Xcode有一个命令行工具altool,您可以使用该工具上载工具以进行公证:
xcrun altool --notarize-app \
--primary-bundle-id "com.example.com" \
--username "[email protected]" \
--password "@keychain:Developer-altool" \
--asc-provider "ABCD123456" \
--file "build/hello-1.0.pkg"
这username是您的开发者帐户电子邮件。
该asc-provider是你的十位数组ID。如果您只是单个团队的成员,则无需提供此信息。
密码使用一个特殊的@keychain:关键字,该关键字告诉altool您从名为的钥匙串项中获取应用程序专用的密码Developer-altool。(还记得我们之前创建的吗?)
这需要一段时间。当命令成功将pkg上传到Apple的公证服务器时,它将返回RequestUUID。您的公证请求将被排队,并最终得到处理。您可以使用以下方法检查请求的状态:
xcrun altool --notarization-info "Your-Request-UUID" \
--username "[email protected]" \
--password "@keychain:Developer-altool"
该过程完成后,Apple还将向您的开发人员帐户发送电子邮件。我的经验很少会花费一两分钟以上的时间。(在中欧时区可能是一个优势)。该过程完成后,您可以运行上面的notarization-info命令以获取一些详细信息。该信息将包含一个包含更多信息的链接,当您的请求被拒绝时,该链接将非常有用。
请注意,信息链接会在24小时左右后失效。您应该复制任何您想要保留的信息。
验证成功后的邮件
完成流程
除了确认或拒绝您的请求外,您不会从Apple得到任何回报。Mac下载您的安装程序包并验证其公证状态时,它将与Apple的公证服务器联系,他们将确认或拒绝该状态。
如果Mac当前处于脱机状态,或者位于阻止访问Apple服务器的代理或防火墙之后,则它无法验证您的pkg文件是否已经过公证。
但是,您可以将公证单“装订”到pkg文件,因此客户端不需要连接到服务器:
xcrun stapler staple build/hello-1.0.pkg
您还可以stapler用来验证过程是否顺利:
xcrun stapler validate build/hello-1.0.pkg
但由于stapler取决于要安装的开发人员工具,因此通常应首选spctl检查公证:
spctl --assess -vvv --type install build/hello-1.0.pkg
流程自动化
显然,我构建了一个脚本来自动化所有这些。将以下脚本放在项目文件夹的根目录中,使用您的信息在脚本的开头(第20-38行)修改变量,然后运行它。
该脚本将构建该工具,创建一个已签名的pkg,将其上传以进行公证,等待结果,然后装订pkg。
#!/bin/zsh
# pkgAndNotarize.sh
# 2019 - Armin Briegel - Scripting OS X
# place a copy of this script in in the project folder
# when run it will build for installation,
# create a pkg from the product,
# upload the pkg for notarization and monitor the notarization status
# before you can run this script:
# - set release signing of the tool to 'Developer ID Application'
# - enable the hardened run-time
# - change the 'Installation Build Products Location' to `$SRCROOT/build/pkgroot`
#
# you want to add the `build` subdirectory to gitignore
# put your dev account information into these variables
# the email address of your developer account
dev_account="[email protected]"
# the name of your Developer ID installer certificate
signature="Developer ID Installer: First Last (ABCD123456)"
# the 10-digit team id
dev_team="ABCD123456"
# the label of the keychain item which contains an app-specific password
dev_keychain_label="Developer-altool"
# put your project's information into these variables
version="1.0"
identifier="com.example.hello"
productname="Hello"
# code starts here
projectdir=$(dirname $0)
builddir="$projectdir/build"
pkgroot="$builddir/pkgroot"
# functions
requeststatus() { # $1: requestUUID
requestUUID=${1?:"need a request UUID"}
req_status=$(xcrun altool --notarization-info "$requestUUID" \
--username "$dev_account" \
--password "@keychain:$dev_keychain_label" 2>&1 \
| awk -F ': ' '/Status:/ { print $2; }' )
echo "$req_status"
}
notarizefile() { # $1: path to file to notarize, $2: identifier
filepath=${1:?"need a filepath"}
identifier=${2:?"need an identifier"}
# upload file
echo "## uploading $filepath for notarization"
requestUUID=$(xcrun altool --notarize-app \
--primary-bundle-id "$identifier" \
--username "$dev_account" \
--password "@keychain:$dev_keychain_label" \
--asc-provider "$dev_team" \
--file "$filepath" 2>&1 \
| awk '/RequestUUID/ { print $NF; }')
echo "Notarization RequestUUID: $requestUUID"
if [[ $requestUUID == "" ]]; then
echo "could not upload for notarization"
exit 1
fi
# wait for status to be not "in progress" any more
request_status="in progress"
while [[ "$request_status" == "in progress" ]]; do
echo -n "waiting... "
sleep 10
request_status=$(requeststatus "$requestUUID")
echo "$request_status"
done
# print status information
xcrun altool --notarization-info "$requestUUID" \
--username "$dev_account" \
--password "@keychain:$dev_keychain_label"
echo
if [[ $request_status != "success" ]]; then
echo "## could not notarize $filepath"
exit 1
fi
}
# build clean install
echo "## building with Xcode"
xcodebuild clean install -quiet
# check if pkgroot exists where we expect it
if [[ ! -d $pkgroot ]]; then
echo "couldn't find pkgroot $pkgroot"
exit 1
fi
## build the pkg
pkgpath="$builddir/$productname-$version.pkg"
echo "## building pkg: $pkgpath"
pkgbuild --root "$pkgroot" \
--version "$version" \
--identifier "$identifier" \
--sign "$signature" \
"$pkgpath"
# upload for notarization
notarizefile "$pkgpath" "$identifier"
# staple result
echo "## Stapling $pkgpath"
xcrun stapler staple "$pkgpath"
echo '## Done!'
# show the pkg in Finder
open -R "$pkgpath"
exit 0
链接和视频
这些链接和视频,特别是霍华德·奥克利(Howard Oakley)的帖子以及汤姆·布里奇(Tom Bridge)的PSU演示文稿,都非常有用。也要感谢同事阿诺德(Arnold)向我展示了这一点甚至是可能的。
- 霍华德·奥克利(Howard Oakley):为Catalina构建和交付命令工具
- 汤姆·布里奇(Tom Bridge):PSU会议讨论与跟进
- Apple支持:为macOS Catalina公证Mac软件
- Apple支持:使用应用专用密码
- Apple Developer:分发前对您的应用程序进行公证
- WWDC 2019:关于公证的一切
- WWDC 2019:macOS安全性方面的进步
- Apple Developer:解决常见的公证问题
- Apple Developer: Customizing the Notarization Workflow