如何对 MacOS 应用程序进行代码签名?

Bry*_*een 2 macos xcode code-signing code-signing-certificate

我工作的大学里有一位教授开发了一个 MacOS 应用程序,他需要签名,这样当用户尝试运行它时,它就不会被 MacOS 阻止。我已经获得了他的 CSR 并获得了为他创建的 Apple 开发人员证书(使用“临时”分发选项,该选项创建了一个名为“distribution.cer”的证书文件)。

我在 Apple 开发者网站上搜索了有关如何使用 XCode 签署应用程序的信息,但我不太能理解这些说明,因为我不是 XCode 用户或 Apple 开发人员。

据我所知,您还可以从终端签署应用程序,这是正确的吗?如果是这样,它是否仅适用于.pkg 安装程序,或者也适用于预编译的应用程序( .app 文件)?

Tre*_*rev 6

代码签名

\n

苹果证书

\n
    \n
  1. 开发者 ID 应用程序证书 - 签署 macOS 应用程序以便在 Mac App Store 之外分发。
  2. \n
  3. 开发人员 ID 安装程序证书 - 签署应用程序的安装程序包(如果有)以便在 Mac App Store 之外分发。
  4. \n
\n

签署应用程序

\n

在终端的命令行上:

\n
codesign -f -o runtime --timestamp -s "Developer ID Application: YOUR NAME (TEAM_ID)" /path/to/bundle.app\n
Run Code Online (Sandbox Code Playgroud)\n

公证

\n

请注意,自 macOS 10.14.5 (Mojave) 起,使用新 Apple 开发者证书签名的软件必须经过公证。代码签名不再足以绕过 Gatekeeper。

\n

Apple 的公证服务要求您:

\n
    \n
  • 为您分发的所有可执行文件启用代码签名。
  • \n
  • 为您的应用程序和命令行目标启用强化运行时功能(运行协同设计工具时包括 -o 运行时选项)。
  • \n
  • 使用 \xe2\x80\x9c 开发人员 ID\xe2\x80\x9d 应用程序、内核扩展或安装程序证书作为代码签名签名。
  • \n
  • 在代码签名中包含安全时间戳(运行代码签名工具时包含 --timestamp 选项)。
  • \n
  • Don\xe2\x80\x99t 包含 com.apple.security.get-task-allow 权利,并将值设置为 true 的任何变体。
  • \n
  • 链接到 macOS 10.9 或更高版本的 SDK。
  • \n
\n

第 1 步 - 创建磁盘映像

\n

通过打开终端并运行以下命令来创建应用程序的磁盘映像:

\n
hdiutil create -volname MyApp -srcfolder /path/to/MyApp.app -ov -format UDBZ MyApp.dmg\n
Run Code Online (Sandbox Code Playgroud)\n

第 2 步 - 对磁盘映像进行代码签名

\n

通过打开终端并运行以下命令对磁盘映像进行代码签名:

\n
codesign -s "Developer ID Application: YOUR NAME (TEAM ID)" --timestamp MyApp.dmg\n
Run Code Online (Sandbox Code Playgroud)\n

第 3 步 - 生成应用程序专用密码

\n

生成应用程序专用密码,请参阅此 Apple 支持文章。注意:这是特定于公证应用程序 (xcrun altool) 的密码,而不是特定于正在公证的应用程序。因此,您只需执行一次此操作,但请确保复制生成的密码并将其保存在某个位置。

\n

第 4 步 - 将磁盘映像上传到公证服务

\n

注意:当您对容器磁盘镜像进行公证时,altool 也会对里面的应用程序进行公证,因此您可以跳过对应用程序本身进行公证的步骤。

\n

打开终端并运行以下命令,将磁盘映像文件上传到 Apple 公证服务:

\n
xcrun altool --notarize-app --primary-bundle-id "<your identifier>" -u "<your email>" -p "<app-specific pwd>" -t osx -f /path/to/MyApp.dmg\n
Run Code Online (Sandbox Code Playgroud)\n

Primary-bundle-id 可帮助您跟踪来自公证服务的自动通信。您提供的值不需要与提交的应用程序的捆绑包标识符匹配或具有任何特定值。它只需要对你有意义。每当公证服务向您发送有关给定 altool 提交的电子邮件时,都会包含该值。

\n

如果上传成功,您应该会收到类似于以下内容的输出:

\n
No errors uploading \'MyApp.dmg\'.\nRequestUUID = 3af4e56f-162b-75bc-827f-7233f92bf20c\n
Run Code Online (Sandbox Code Playgroud)\n

第5步 - 检查公证流程

\n

公证过程通常需要不到 15 分钟,因此您可能需要不时通过打开终端并运行以下命令来检查其进度:

\n
xcrun altool --notarization-history 0 -u "<your email>" -p "<app-specific pwd>"\n
Run Code Online (Sandbox Code Playgroud)\n

当公证过程成功完成时,上述命令将返回类似于以下内容的信息:

\n
Notarization History - page 0\n\nDate                      RequestUUID                          Status    Status Code Status Message   \n------------------------- ------------------------------------ ------- ----------- ---------------- \n2019-12-08 06:24:03 +0000 3af4e56f-162b-75bc-827f-7233f92bf20c success 0           Package Approved \n
Run Code Online (Sandbox Code Playgroud)\n

您还应该收到来自 Apple 的类似于以下内容的电子邮件,以表示公证成功:

\n
Dear <First_Name>,\nYour Mac software has been notarized. You can now export this software and distribute it directly to users.\nBundle Identifier: com.example.MyApp.001\nRequest Identifier: 3af4e56f-162b-75bc-827f-7233f92bf20c\nFor details on exporting a notarized app, visit Xcode Help or the notarization guide.\nBest Regards,\nApple Developer Relations\n
Run Code Online (Sandbox Code Playgroud)\n

第 6 步 - 将票证钉到磁盘映像上

\n

公证过程会生成一张票证,告诉 Gatekeeper 您的申请已经过公证。公证成功完成后,下次任何用户尝试在 macOS 10.14 或更高版本上运行您的应用程序时,Gatekeeper 将在线找到票证。这包括在公证之前下载您的应用程序的用户。

\n

步骤 5 收到“Package Approved”状态消息后,您还应该使用订书机工具将票证附加到磁盘映像文件中,以便将来的发行版包含该票证。这可以确保即使网络连接不可用,Gatekeeper 也可以找到票证。

\n

要将票证装订到磁盘映像文件,请打开终端并运行以下命令:

\n
xcrun stapler staple /path/to/MyApp.dmg\n
Run Code Online (Sandbox Code Playgroud)\n

如果命令成功完成,输出应类似于:

\n
Processing: /Path/to/MyApp.dmg\nProcessing: /Path/to/MyApp.dmg\nThe staple and validate action worked!\n
Run Code Online (Sandbox Code Playgroud)\n

第 7 步 - 验证磁盘映像的公证

\n

要验证磁盘映像的公证,请打开终端并运行以下命令:

\n
spctl -a -vv -t install MyApp.dmg\n
Run Code Online (Sandbox Code Playgroud)\n

公证过程的成功验证应产生类似于以下内容的输出:

\n
MyApp.dmg: accepted\nsource=Notarized Developer ID\norigin=Developer ID Application: <Developer Name> (<TEAM_ID>)\n
Run Code Online (Sandbox Code Playgroud)\n

第 8 步 - 验证申请的公证

\n

要验证应用程序的公证,请安装应用程序,打开终端并运行以下命令:

\n
spctl -a -vv /Applications/MyApp.app\n
Run Code Online (Sandbox Code Playgroud)\n

公证过程的成功验证应产生类似于以下内容的输出:

\n
/Applications/MyApp.app: accepted\nsource=Notarized Developer ID\norigin=Developer ID Application: <Developer Name> (<TEAM_ID>)\n
Run Code Online (Sandbox Code Playgroud)\n

重要提示:通过将应用程序放入应用程序目录来测试该应用程序。当处于“已安装”位置时,Gatekeeper 会以不同方式对待它。

\n

或者,Apple 推荐的验证应用程序公证的方法是打开终端并运行以下命令:

\n
xcrun stapler validate MyApp.app\n
Run Code Online (Sandbox Code Playgroud)\n

公证过程的成功验证应产生类似于以下内容的输出:

\n
Processing: MyApp.app\nThe validate action worked!\n
Run Code Online (Sandbox Code Playgroud)\n

  • 这就是为什么没有人愿意为 Mac 开发开源应用程序的原因。 (5认同)