12

在某些情况下,我正在使用 jpackage 实用程序来尝试创建一个签名的 DMG 文件以交付给我的用户。我需要签署这个 DMG 的原因是因为我想对软件进行公证。顺便说一句,我不确定是否可以(还)使用 jpackage 进行公证,但我还是在尝试。

但是,我在使用 jpackage 的内置代码签名选项时遇到了问题,这是成功公证的先决条件。

我正在使用选项运行 jpackage --mac-sign --mac-package-signing-prefix CardrDebate --mac-signing-key-user-name "Developer ID Application: ********** (*******)"(我已经编辑了实际的开发人员 ID,因为它在 StackOverflow 上是公开的)。

创建 jpackage 应用程序映像后,我通过导航到几个生成的 .dylib 文件并尝试测试生成的代码是否实际上已签名codesign -vvv {filename}.dylib,并且 codesign 说该对象根本没有签名(不是它被错误地签名,而是它只是根本没有签名)。

因此,我相信我的问题是由于我(可能)在 macOS 上错误地使用了 jpackage 的签名选项。我应该如何使用这些?

4

4 回答 4

20

我将继续回答我自己的问题,因为我最终弄清楚了如何签署我的应用程序并从 Apple 公证服务中成功对其进行公证(我的产品是http://cardr.x10.bz)。

  1. 使用 jpackage 的 app-image 选项生成未签名的应用程序包。

  2. 使用自动 bash 脚本对应用程序包内的所有 dylib 和可执行文件进行代码设计,使用codesign -vvv --options runtime --deep --force --sign "Developer ID Application: ********" <filename>.

  3. 这是一个多步骤的过程,所以我将其拆分为 A/B/C。

3A) 在 MyApp.app/Contents/mods/ 中找到所有包含嵌入式 .dylib 文件的 jar 文件,并将这些文件解压缩到特定文件夹(或编写一个小程序来为您执行此操作)。对我来说,我的应用程序依赖于 JavaFX,因此许多 JavaFX 库在 jar 文件中包含 .dylib 文件。但是,如果您只是使用默认的 Java 库,您应该可以跳到第 4 步,因为默认的 Java 库不包含 .dylib 文件。我们需要执行此步骤的原因是因为 Apple 的公证服务也会检查这些嵌入的 .dylib 文件以进行代码签名。

3B) 使用自动 bash 脚本对您刚刚提取的所有 dylib 文件进行代码设计,使用codesign -vvv --options runtime --deep --force --sign "Developer ID Application: ********" <filename>.

3C) 将每个已签名的 .dylib 文件添加回各自的 jar 文件中,以替换原始未签名的嵌入式 .dylib 文件。这是一个可能会派上用场的命令:jar uf <path to jar file> <path to dylib file>. 请注意,指定的第二个路径,即 dylib 文件的路径,也应该是 dylib 在存档中的相对位置。在这里查看更多详细信息 - https://docs.oracle.com/javase/tutorial/deployment/jar/update.html

  1. 现在您已经对 .app 中的每个可执行文件和 dylib 文件进行了签名,是时候对 .app 本身进行签名了。运行codesign -vvv --force --sign "Developer ID Application: ********" MyApp.app

  2. 现在您已经签署了 .app,您需要在应用程序包上运行 jpackage 以从中创建 DMG 或 PKG。随意使用 jpackage mac 签名功能,它将对外部 DMG/PKG 进行签名。请注意,该属性--mac-signing-key-user-name "My Developer Account Name (*******)"不应包含证书的“开发者 ID 应用程序/安装程序”部分。

  3. 最后,您已经创建了一个已签名的 PKG/DMG 以供公证。使用xcrun altool --notarize-app --username <apple-id> --password <app-specific-password> <MyApp.dmg or MyApp.pkg>. 等待公证完成并确保它被批准。

  4. 如果公证成功(应该),您可以使用xcrun stapler staple MyApp.pkg.

希望这可以帮助!

于 2020-04-07T23:50:59.990 回答
4

有关我的应用程序 ( Unattach )的工作端到端脚本,请参阅package.shdarwin部分。

于 2020-05-20T08:32:47.957 回答
4

仅供参考 - 在 JDK 14.0.1 中深入研究了这个问题,并希望将知识作为另一个临时解决方案分享,直到 jpackage 正常工作。

在JDK 14源码路径:src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal

文件MacAppBundler.java包含这些行 (81 & 82): "Developer ID Application:" + SIGNING_KEY_USER.fetchFrom(params),

其中 SIGNING_KEY_USER 从命令行获取--mac-signing-key-user-name参数的值。

使用这些行使用 jpackage 对 DMG 进行签名总是失败。(“开发者 ID 申请:”与我的证书名称不匹配。)

更改这些行以删除“开发人员 ID 应用程序:”和以下“+”号。在调用 jpackage 时,使用证书的全名作为参数值:

--mac-signing-key-user-name "第 3 方 Mac 开发者应用程序:John Smith (ABCDEFGHIJ)"

jpackage 现在(显然)将构建并签署 DMG。实际上并没有尝试将其提交到 Apple Store,因此这可能仍然不完整。

有趣的是,MacAppStoreBundler.java源代码确实包含正确的“3rd Party Mac Developer Application:”和“3rd Party Mac Developer Installer:”前缀字符串,因此怀疑 jpackager 实际上调用了错误的方法——但尚未解决。可能 jpackage 需要一些额外的参数来准确指定应该做什么(但你会认为'--type dmg'会调用正确的逻辑)。

重现的基本(笨拙)步骤:

  • 从https://hg.openjdk.java.net/jdk下载源码(选择 jdk14,commit 6c954123ee8d)。
  • 下载 .zip(或 .gz 或 .bz2)并将其解压缩到工作目录中
  • 使用任何文本编辑器按照“src”的路径并更改 MacAppBundler.java,如上所述。
  • 打开终端窗口,然后 cd 进入“src”目录
  • 运行 'make all' 编译整个 JDK 14
  • 运行 src/build/macosx-x86_64-server-release/images/jdk/bin/jpackage ...参数...
于 2020-05-24T18:05:58.733 回答
2

我只想更新这个过程。我在构建过程中有一个使用 Java 16 的 JavaFX 11 应用程序。Soham 所描述的方法是有效的。但是,在这里我发现了一些要点:

  1. 使用 Java 16,您不再需要“--deep”选项来签署应用程序映像(也不建议部署)。
  2. 我需要用于签名的权利文件,即用于签名的--entitlement 选项。否则应用程序在签名后不会启动。
  3. 可以使用 jpackage 签名参数对安装程序进行签名。
  4. 将安装程序作为 zip 上传以进行公证按预期工作。
于 2021-08-09T02:57:05.110 回答