如何为macOS Catalina 10.15签署应用程序

图片

[注意 transl .:翻译引起了Habré广泛讨论的帖子 ,我对Apple提出的针对软件开发人员的新规则感兴趣。 本文讨论与一位游戏开发人员掌握规则的个人经验。]

引言


在新版本的macOS中,Apple对曾经被推荐的应用程序提出了某些要求:64位可执行文件,签名和公证。 不满足这些要求的应用程序将不再启动。

这样做是为了保护用户的工作并防止恶意程序的传播,但是同时,这也给生活带来了很大的困难,特别是对于那些Mac不是主要开发平台但仍然希望启动或继续支持Mac的人们。

对于在Steam上发布Mac游戏的游戏开发人员而言尤其如此。 在最近的更改之前,Steam发行的游戏不需要签名和公证,但现在它们必须遵守与其他所有人相同的规则。

我刚刚弄清楚如何实现我的飞艇的这些要求:征服天空游戏。 飞艇使用Java工作,因此需要JVM,但一般而言,其他所有内容都适用于大多数开发人员。

这是我了解到的关于签名和公证不是Xcode直接编译的Mac应用程序的知识。 请注意,这些信息是从我自己的研究中获得的,可能并非100%准确。 欢迎提出问题和更正。

背景知识


本文讨论签名和公证。 获取程序的64位可执行文件是编译器或开发环境的任务。

在macOS上,应用程序通常打包在包中-包含可执行文件以及其他资源和元数据的文件夹。 对捆绑软件进行签名意味着要创建捆绑软件内容的加密校验和,然后创建带有Apple颁发给开发人员的证书的加密签名。 签名是您个人保证应用程序正确行为的声明。 如果捆绑软件的内容发生了更改,则校验和也发生了变化,并且签名也不再与它们对应,从而警告操作系统已对捆绑软件进行了未经授权的更改。

应用程序签名已经存在了很多年。 稍后,公证也需要申请。 公证意味着您提交了已签名的Apple应用程序,并且公司将执行其他检查并注册该应用程序。 如果公证成功,则将公证“粘贴”到您的应用程序中,这样,无法访问Internet的脱机计算机也可以确保已对应用程序进行了公证。

这是使用纸质文档的一种隐喻。 开发人员将捆绑在一起的所有组成应用程序的部分收集在一起。 然后,他创建了包的所有元素的列表(校验和)并对此列表签名(带有数字签名),然后将其粘贴到包。 然后,他将签名的捆绑包交给公证人Yablokov先生,后者检查捆绑包是否一切正常,然后进行注册。 他给开发人员收据,订书机将其附加到捆上。 也就是说,如果开发人员说该应用程序是安全的,而Yablokov先生也说该应用程序是安全的,那么很可能是这样。 并且,如果一个坏人试图更改其内容,那么捆绑元素列表将不再与之对应,并且用户将知道没有必要使用它。

要求条件


对应用程序进行签名和公证需要什么:

  • 一台足以运行Xcode 11的Mac计算机,即足以运行macOS 10.14.3的Mac计算机。 如果尚未安装Xcode,则需要25 GB的可用空间。
  • 如果您还不是Apple的正式开发人员,则需要Apple ID登录和约110美元的会员费。

两因素验证


如果您还没有,请为您的Apple ID启用两因素身份验证。 可以从任何智能设备或Mac上完成此操作。 在Mac上,转到系统偏好设置的iCloud控制面板。 顶部应该有一个面板建议启用2FA。

会员购买


使用您的Apple ID登录到https://developer.apple.com/并进入“成员资格”选项卡。 如有必要,购买或升级您的Apple Developer Program会员资格。 请注意,在Apple的内部系统上处理购买交易需要花费一些时间,因此,如果您无法生成证书(请参阅下文),请喝一杯茶并静下来。

申请编号


您可能需要在开发人员的后端注册应用程序捆绑包ID。 捆绑包ID可以在YourApp.app/Contents/Info.plist中找到。 (您可以通过在应用程序包上单击鼠标右键,然后选择“显示软件包内容”来打开应用程序包。)标识符应为com.yourcompanyname.applicationname,例如,我的游戏《飞艇》具有com.zarkonnen.airships。

要注册ID,请登录https://developer.apple.com/ ,在左窗格中选择“证书,ID和配置文件”,然后在下一页中选择“标识符”。 然后,您可以单击“ +”按钮添加应用程序标识符。

申请密码


要从命令行签名,您将需要应用程序密码,因此请访问https://appleid.apple.com/account/manage并生成它。

Xcode和工具


通过Mac App的App Store安装Xcode。 然后从https://developer.apple.com/download/more安装Xcode命令行工具。 您需要Xcode 11或所用Xcode版本的命令行工具。

证明书


启动Xcode,转到“首选项”,打开“帐户”标签。 如有必要,将您的Apple ID添加到帐户列表中。 然后单击右下角的“管理证书...”按钮。 显示用于签署应用程序的证书。 您需要“开发人员ID应用程序”证书; 如果它不在列表中,则创建它。 单击“完成”,然后在“首选项:帐户”窗口中单击“下载”,以在本地下载证书。

申请准备


为了使应用程序在新系统上正常运行,可执行文件和库必须为64位。

另外,Mac OS执行一项称为“易位”的操作:出于安全原因,它将运行中的应用程序捆绑包移动到随机位置。 对于我的应用程序,这表现为它找不到位于应用程序捆绑包旁边的数据文件。 您可以获得应用程序捆绑包的原始位置,但是我只需将所有内容放入捆绑包即可解决了该问题。

权限(权利)


这些是开发人员与代码签名一起添加的特殊权限,允许已签名的应用程序执行某些操作。 如果使用Xcode编译应用程序,则它将自行完成所有操作; 否则,您将需要创建一个plist文件,其中包含所需的所有权利。 可以使用Xcode创建Plist文件,并且在https://developer.apple.com/documentation/bundleresources/entitlements中有权利列表。

要使用Xcode创建新的plist文件,请选择“新建文件”,然后在出现的列表中单击“属性列表”。 将具有所需权利的元素添加到根字典中; 它们的含义是布尔值:是。


就我的游戏而言,因为它是用Java编写的,所以我需要以下权限才能使JVM正常工作:com.apple.security.cs.allow-jit,com.apple.security.cs.allow-unsigned-executable-memory,com。 apple.security.cs.disable-executable页面保护,com.apple.security.cs.disable-library-validation,com.apple.security.cs.allow-dyld-environment-variables。 对于用户而言,它们看起来令人生畏,因此,如果您不需要它们,则不要添加它们。

在本文的后面,我们将假定您已将权利放置在名为entitlements.plist的文件中。

签收


这是创建数字签名通知的过程:有权访问签名证书的人保证此特定的应用程序捆绑包可靠且无恶意。 签名后,应用程序捆绑软件中的任何更改(附加公证确认除外,请参见上文)均会使签名无效,并需要重新签名捆绑软件。

这也意味着您的应用程序不应更改应用程序捆绑包中的任何内容,例如,不要在其中放置缓存。

应用程序捆绑包中的每个可执行文件和动态库均单独签名。 在某些情况下,库可能已经签名。 也就是说,通过依次对每个元素进行签名然后对整个捆绑包进行签名,来对捆绑包进行签名会更加礼貌和冷静。 如果任何元素已经具有签名,则它将保留在其位置。

粗略但有效的方法是强制进行深度签名,也就是说,您的签名将应用于应用程序包的所有元素,从而替换所有先前的签名。 这正是我们将要执行的操作,因为它更简单,并且以前的签名可能无效或不够强大。

您将需要以下可怕的命令:

codesign -s "Developer ID Application: <YourName>" --timestamp --options runtime -f --entitlements entitlements.plist --deep YourApp.app

--timestamp选项意味着成功的公证所必需的有效时间戳将与签名一起嵌入。

选项--options runtime选项表示签名包括“强化的运行时”,这对于成功的公证也是必需的。

您可以通过团队了解签名

codesign -d -vvvv YourApp.app

您还应该运行该应用程序,以确保它在签名后能够继续工作。

如果要以更礼貌的方式对元素进行签名,请从命令中删除-f--deep命令,首先对应用程序内的所有可执行文件和库进行签名,然后对整个应用程序进行签名。

公证


对应用程序进行签名后,您需要将其提供给Apple系统进行公证,以便说:“看,我已经签了这东西。”

为此,首先使用ditto命令将应用程序压缩为特殊的zip文件:

/usr/bin/ditto -c -k --keepParent YourApp.app YourApp.zip

仅使用Finder或命令行将应用程序包装为zip格式将不起作用。

然后发送zip进行公证:

xcrun altool --notarize-app --primary-bundle-id "<id>" -u "<appleid>" -p "<app-specific password>" --file YourApp.zip

一个例子:

xcrun altool --notarize-app --primary-bundle-id "com.zarkonnen.airships" -u "dave@hotmail.com" -p "bwnh-pbbt-llpt-xxxx" --file Airships.zip

可以通过查看YourApp.app/Contents/Info.plist来找到捆绑包ID。 (您可以通过右键单击应用程序包并选择“显示软件包内容”来打开它们。)

公证可能需要一段时间。 通常是几秒钟或几分钟,但有时可能是一个小时。 给自己倒更多的茶,或更浓的东西,自己选择。 迟早您会得到如下信息:

No errors uploading 'YourApp.zip'.
RequestUUID = 29926ae6-f551-4d54-b283-e29d6f9b9156


现在,我们可以使用以下命令来检查已传输包的状态:

xcrun altool --notarization-info <RequestUUID> -u -u "<appleid>" -p "<app-specific password>"

一个例子:

xcrun altool --notarization-info 29926ae6-f551-4d54-b283-e29d6f9b9156 -u "dave@hotmail.com" -p "bwnh-pbbt-llpt-xxxx"

将会显示类似的内容:

          日期:2019-10-08 06:59:58 +0000
          哈希值:0774fb95035408bacecebd64935a611ecd27b45ad9cbf3cc1aa48fa1e0eaa649
     LogFileURL:https://osxapps-ssl.itunes.apple.com/itunes-assets/Enigma123 / ...
        现状:成功
   状态码:0
状态消息:包已批准 

我再说一遍,确认通常需要大约15分钟,但有时对于同一应用程序则需要几个小时。 是的,那样。

如果状态为失败,则请查看日志文件URL列出的错误。 如果您获得成功,则无论如何都要看一下,因为可能会有警告,而当苹果再次收紧要求时,这些警告很可能会变成错误。

附件


最后,我们将“确认”公证确认到应用程序捆绑包中,以便即使Mac也可以在没有Internet连接的情况下进行检查。 为此,您必须执行一个非常短的命令:

xcrun stapler staple "YourApp.app"

恭喜,您已经注册并公证了Mac应用。 现在,如果在过程中没有更改,则可以通过任何方便的方式分发应用程序捆绑包。

爪哇


如果您与我同在一条船上,并且需要与JVM应用程序一起添加到捆绑软件中,请继续阅读。

有几种方法可以将JVM捆绑软件与Java应用程序结合在一起。 我会推荐AppBundler,这是一项为您完成所有工作的蚂蚁任务。 最初,可以从java.net下载AppBundler,但是由于Oracle忽略了Java平台的其余部分,现在您必须从https://github.com/TheInfiniteKind/appbundler下载最新版本。

在这里可以找到源代码和文档,但找不到jar,因为假定您正在使用Maven。 如果您不使用Maven,则可以从以下位置获取jar: https//jar-download.com/artifacts/com.panayotis/appbundler

请按照github页上文档中的说明进行配置。 我个人使用NetBeans,为了解决该问题,我在build.xml中插入了以下几行:

 <target name =“-post-jar”>
   <taskdef name =“ bundleapp” 
     classpath =“ lib / appbundler-1.1.0.jar”
     classname =“ com.oracle.appbundler.AppBundlerTask” />
   <bundleapp 
       jvmrequired =“ 1.7”
       outputdirectory =“ / home / zar /桌面”
      名称=“飞艇”
       displayname =“飞艇”
       executeName =“飞艇”
      标识符=“ com.zarkonnen.airships”
       shortversion =“ 1”
      版本=“ 1”
       mainclassname =“ com.zarkonnen.airships.Main”
      版权=“ 2019 David Stark”
       applicationCategory =“ public.app-category.games”>
       <classpath dir =“ dist” />
       <runtime dir =“ / home / zar /桌面/ jdk-11.0.4.jdk / Contents / Home” />
       <arch name =“ x86_64” />
       <option value =“-Dapple.laf.useScreenMenuBar = true” />
       <option value =“-Dcom.apple.macos.use-file-dialog-packages = true” />
       <option value =“-Dcom.apple.macos.useScreenMenuBar = true” />
       <option value =“-Dcom.apple.mrj.application.apple.menu.about.name =飞艇” />
       <option value =“-Xdock:名称=飞艇” />
       <option value =“-Dcom.apple.smallTabs = true” />
       <option value =“-Dfile.encoding = UTF-8” />
       <option value =“-Xmx1024M”名称=“ Xmx” />
   </ bundleapp>
 </ target> 

这是创建jar文件后执行的任务。 它使用appbundler-1.1.0.jar创建带有嵌入式JVM的应用程序包。

可以从https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html下载我使用的JDK。 我选择版本11是因为它具有LTS(长期支持),但是使用了旧的Oracle许可条款,而版本13具有一组奇怪的新许可证限制。

还有更多合法免费的OpenJDK JVM,但是我无法让它们与应用程序捆绑程序一起使用。

注意:JVM是“ Java虚拟机”。 JRE是一个“ Java运行时环境”,其中包括JVM和其他元素,例如Java更新程序。 JDK是一个“ Java开发工具包”,由JRE以及编写Java程序所需的内容(例如编译器)组成。 在Java 8之前,JRE分别可供最终用户使用,但此后仅JDK可用,因此我们将Java开发环境与计算机游戏相关联。

您应该能够对结果包进行深入的签名和公证。 AppBundler文档提供了很多其他选项,例如添加图标,文件类型关联以及为应用程序生成精简的JVM。

进一步阅读



加法


  • Reddit AMemoryOfEternity的用户在Steam开发者论坛上提出了一个问题,事实证明,尽管根本不需要有关Steam应用程序的通知。 它们应为64位,但尚不清楚是否必须对它们进行签名。 链接,需要访问Steamworks
  • Apple暂时放宽了公证规则,因此,它允许您对没有强化运行时,具有子组件,没有开发人员ID,没有时间戳等的应用程序进行公证。 这样的事情仍会在公证报告中显示为警告,因此为了照顾将来,最好尝试摆脱它们。
  • Valve表示,要使Steam API正常工作,您需要授予com.apple.security.cs.allow-dyld-environment-variables权利:“ Steam通过DYLD_INSERT_LIBRARIES注入dylib API,默认情况下,加固的运行时会阻止dylib API,但是dylib API本身已签名并且必须经过测试,因此只需添加权限“ com.apple.security.cs.allow-dyld-environment-variables”即可分配DYLD环境变量。”

Source: https://habr.com/ru/post/zh-CN471816/


All Articles