在macOS上,使用jpackage实用程序进行代码签名和公证化不起作用

13
为了提供一些背景信息,我正在使用jpackage工具创建签名的DMG文件以交付给我的用户。我需要对这个DMG进行签名是因为我想要对软件进行公证。顺便说一下,我不确定是否可以使用jpackage进行公证,但我仍在尝试。 然而,我在使用jpackage的内置代码签名选项时遇到了困难,这是成功进行公证的先决条件。
我使用以下选项运行jpackage:--mac-sign --mac-package-signing-prefix CardrDebate --mac-signing-key-user-name "Developer ID Application: ********** (*******)"(由于此内容在StackOverflow上是公开的,我已经删除了实际的开发者ID)。
创建jpackage应用程序镜像后,我测试了生成的代码是否真正被签名,方法是导航到几个生成的.dylib文件并尝试codesign -vvv {filename}.dylib,结果codesign表示该对象根本没有被签名(并非签名错误,而是根本没有被签名)。
因此,我认为我的问题来自于我在macOS上可能使用不正确的jpackage签名选项。我应该如何使用它们?
4个回答

23

我将回答自己的问题,因为我最终找到了如何签署我的应用程序并从苹果认证服务成功获得认证(我的产品是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文件。我们需要执行这一步的原因是因为苹果的认证服务也会检查这些嵌入的.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 (*******)"应该不包括证书的“Developer ID Application/Installer”部分。

  3. 最终,您已经创建了一个可用于公证的已签名PKG/DMG。使用xcrun altool --notarize-app --username <apple-id> --password <app-specific-password> <MyApp.dmg或MyApp.pkg>来进行公证。等待公证完成并确保获得批准。

  4. 如果公证成功(应该会成功),您可以使用xcrun stapler staple MyApp.pkg将应用程序的票据附加到PKG安装程序上。

希望这可以帮助您!


我按照你的步骤进行了类似的操作。但是,在签署可执行文件时(dylib不需要此标志),我需要添加“--options runtime”,否则我将从验章服务中收到一个错误,指出“可执行文件未启用强化运行时”。问题在于,当我使用“--options runtime”标志对外部.app进行签名后,该应用程序无法运行。然而,当我省略外部应用程序的此标志时,该应用程序可以正常运行。您对此问题有任何想法吗?谢谢。 - Nuntipat Narkthong
谢谢您的评论。我已经更新了帖子,包括--options runtime; 我也不得不使用这个选项,但我只是忘记在帖子中提及它。我不记得我用什么命令签名了 .app,但当我有 Mac 的访问权限时,我会检查并告诉你的。顺便说一下,如果这篇文章对您有所帮助,请给它点赞,以便更多人看到。谢谢! - Soham
@NuntipatNarkthong 我在签署应用程序时没有使用 --options runtime 选项,我只是使用了 codesign -vvv --force --sign <key> MyApp.app。 - Soham
1
显然jdk15ea修复了这个问题https://bugs.openjdk.java.net/browse/JDK-8237490,但我仍然遇到了问题。公证服务仍然显示一个未正确签名的dylib文件`Contents/runtime/Contents/MacOS/libjli.dylib`。 有人能够确认这一点吗? - Christoph S
我也遇到了libjli.dylib的错误 - “二进制文件的签名无效。” - Erel

4

FYI - 我在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总是失败的。(“Developer ID Application:”与我的证书名称不匹配。)

更改这些行以删除“Developer ID Application:”和后面的“+”符号。在调用jpackage时,使用证书的完整名称作为参数值:

--mac-signing-key-user-name“第三方Mac开发人员应用程序:John Smith (ABCDEFGHIJ)”

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

有趣的是,MacAppStoreBundler.java源代码包含正确的“第三方Mac开发者应用程序:”和“第三方Mac开发者安装程序:”前缀字符串,因此怀疑jpackager实际上调用了错误的方法--但尚未解决这个问题。可能jpackage需要一些额外的参数来指定应该执行什么操作(但你会认为'--type dmg'将调用正确的逻辑)。
复制基本(笨拙)步骤:
  • https://hg.openjdk.java.net/jdk下载源代码(选择jdk14,提交6c954123ee8d)。
  • 下载并解压缩.zip(或.gz或.bz2)到工作目录中
  • 使用任何文本编辑器按照上述说明更改MacAppBundler.java中的路径。
  • 打开终端窗口,并进入“src”目录
  • 运行“make all”编译整个JDK 14
  • 运行src/build/macosx-x86_64-server-release/images/jdk/bin/jpackage...parameters...

3

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

  1. 使用Java 16,您不再需要“--deep”选项来签名应用程序映像(也不建议用于部署)。
  2. 我需要一个授权文件进行签名,即使用--entitlement选项进行签名。否则,在签名后该应用程序无法启动。
  3. 安装程序可以使用jpackage sign参数进行签名。
  4. 将安装程序上传为zip以进行公证与预期相符。

3
另一项更新:使用JavaFX/JDK 17.0.2,我按照以下步骤构建了一个.dmg文件。该文件随后可上传至Web服务器,并通过Web浏览器下载:
# no entitlements required.
# no further .dylib or .jar signing required.
jpackage --type dmg --mac-sign --mac-signing-key-user-name "YOUR_DEVELOPER_APPLICATION_ID" [...]

# .dmg signing is required for notarization.
codesign --timestamp -s "YOUR_DEVELOPER_APPLICATION_ID" "DMG_NAME"

# recommended notarization steps with verification
xcrun notarytool submit "DMG_NAME" --wait --keychain-profile "YOUR_PROFILE"
xcrun stapler staple "DMG_NAME"
spctl -a -t open --context context:primary-signature -vv "DMG_NAME"

有人也遇到了jdk19的问题吗?JDK17没问题,但是jdk19出了点问题。 - Christoph S
我很想知道你在jpackage命令中还有什么其他内容。我的命令行的其余部分会导致错误消息包含奇怪的东西,例如--remove-signature和jspawnhelper,这对我来说没有意义 :-( - i2B
1
除了 --type_、--mac-sign_ 和 --mac-signing-key-user-name 之外,我使用了以下参数(及其相应的值):_--runtime-image_、_--icon_、_--name_、_--app-version_、_--vendor_、_--mac-package-identifier_、_--mac-package-name_、_--module_、_--verbose_ 和多个 _--java-options_。 - user27772

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接