当前位置: 首页 > 知识库问答 >
问题:

在 Xcode 外部对 Mac 应用进行数字签名失败

苗冯浩
2023-03-14

我使用Qt5开发了一个Mac应用程序,所以在Xcode之外。我希望GateKeeper允许我的应用程序在客户端的计算机上运行,而不是发出“无法打开,因为无法确认开发人员的身份”警告。

我已经成功地对该应用程序进行了数字签名,但GateKeeper仍然带有此投诉。我有Apple开发者证书(我是团队代理),我的钥匙串说它是有效的。我还安装了两个Apple根证书。

我使用命令行实用程序<code>codesign</code>对应用程序文件夹中的所有二进制文件进行数字签名,此外,我还对应用程序目录本身进行数字签名。在所有情况下,代码设计的响应都是信息性的,不会显示错误。使用codesign,我可以检查所有二进制文件是否都已签名,运行

$ codesign --verify --deep --verbose=2 MyApp.app

显示所有二进制文件都已验证。此外,它还报告:

我的应用程序。应用程序:在磁盘上有效<br>MyApp。应用程序:满足其指定要求

运行:

$ codesign -v --verbose=4 --display MyApp.app   

给予

执行文件=/Users/xxx/trunk/yyy/deploy/release/MyApp。app/Contents/MacOS/MyApp
标识符=aaaa。MyApp<br>Format=bundle with Mach-O thin(x86_64)<br>CodeDirectory v=20200 size=12461 flags=0x0(无)Hash=616 3 location=embedded<br>Hash type=sha1 size=20<br>CDHash=D1C12C783DAC0E8D9A2B749FB896B1558CEC8B6<br>签名大小=8532<br>权限=开发者ID应用程序:XXXXX<br>权威机构=开发者ID认证机构<br>授权机构=苹果根CA<br>时间戳=2015年7月29日12;04:40<br>信息。plist entries=8<br>TeamIdentifier=yyyy<br>密封资源版本=2规则=12文件=10<br>内部要求计数=1大小=180<br>

这似乎没问题。

运行

$ spctl -a -t exec -vv MyApp.app

在所有二进制文件上,结果为

MyApp.app:已接受< br > source =开发者ID < br > origin =开发者ID应用程序:XXXX

这似乎也没问题

在应用程序或应用程序文件夹内的二进制文件上运行XCode命令行工具check-signature:< br >

$ ./check-signature /Users/xxx/trunk/yyy/release/MyApp.app

给出结果

(c) 2014 Apple股份有限公司.保留所有权利

这在所有情况下都是期望的结果。

但GateKeeper仍然不接受该应用程序,并抱怨无法确认开发人员。

[作者于2015年7月17日星期五添加]

我想我已经找到了问题所在。我不知道这是一个功能还是一个OSX错误。堆栈溢出问题19551298给了我很大的帮助。

每当从互联网下载文件时,它都会获得一个与之相关联的扩展文件属性com.apple.quarantine。在Finder中双击这个下载的文件时,网守有两种可能:

>

  • 文件未签名时,会发出“未识别的开发人员等”消息

    当对文件进行数字签名时,会发出“无法确认开发人员等”消息

    在这两种情况下,MessageBox都只有一个按钮,一个OK按钮。单击此按钮时,除了MessageBox关闭外,什么都不会发生。

    如果扩展属性被删除(xattr-d),应用程序将运行、签名或不运行。

    当应用程序通过在应用程序上的Finder中单击鼠标右键,然后单击“打开”菜单操作来启动应用程序时,行为是不同的。再次显示两个消息框中的一个,但现在带有一个额外的按钮,允许用户打开应用程序。同样,已签名和未签名之间的唯一区别是“未识别”或“未确认”消息。我不期望我的客户能够分辨出差异。因此,对应用程序进行签名是徒劳的。

    根据Apple支持文档,我期望在双击下载的应用程序时GateKeeper的另一种更好的行为(也许文档已过时,或者我误读了它):

    > < li>

    如果应用程序已签名,网守应显示一个消息框,显示“从互联网下载等”和一个按钮,显示“仍要继续吗?”

    如果应用程序未签名,则带有单个OK按钮和文本“身份不明的开发人员等”的MessageBox

  • 共有3个答案

    冯皓
    2023-03-14

    我的两位:

    >

  • 要真正验证协同设计,我必须将我的DMG上传到服务器并使用浏览器下载它,或者手动设置隔离属性:

    APP_PATH="Any.app"
    xattr -w com.apple.quarantine '0081;5a37dc6a;Google Chrome;F15F7E1C-F894-4B7D-91B4-E110D11C4858' "$APP_PATH"
    xattr -l "$APP_PATH" # You should see the quarantine attribute here
    open "$APP_PATH"
    

    如果您的应用程序正确签名,您应该会看到一个带有“打开”按钮的系统对话框。

    我通过查看从Internet下载的另一个. app找到了隔离属性的值。我不知道值是什么意思。

    我真的不明白为什么spctl命令说“接受”,即使守门人服务拒绝打开应用程序。

    我有“身份不明的开发人员”消息框,因为我的Qt框架被引用为“@rpath/ QtCore.framework”。将其更改为“@application_path/../Frameworks/QtCore.framework“使用install_name_tool修复了我的应用程序中的问题。

  • 麹学文
    2023-03-14

    阿德拉格的问题和自我回答在帮助我克服同样的问题方面是无价的。然而,尽管他的食谱很好,但有些说法并不完全正确,所以我想补充几点。

    • 没有必要用@executable_path语句替换二进制文件和动态库中的@rpath条目@只要嵌入二进制文件中的实际rpath条目不是绝对的,rpath语句就可以。您可以找到大量使用rpath的有效Qt应用程序包。你可以按照adlag说的做,但你可能是在为自己工作
    • 有关如何使用otool-l$file|grep-A2 LC_RPATHinstall_name_tool-delete_RPATH$path$file,请参见上面的jil评论,以检查和删除二进制文件和库中的嵌入路径。
    • 看https://developer.apple.com/library/content/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG207,以清楚地解释为什么GateKeeper抱怨二进制文件中的路径,以及如何在syslog中看到具体的抱怨
    • 如果绝对路径有问题,应该首先尝试修复构建,而不是事后使用install_name_tool
    • 如果您正在使用cmake,这可能会有所帮助:https://cmake.org/Wiki/CMake_RPATH_handling#Mac_OS_X_and_the_RPATH
    • 不要在动态库文件上运行spctl-a-t exec-vv/path/to/binary。您将获得有关资源信封的错误。这是意料之中的,不是问题
    • 根据我的经验,macdeployqt工作正常。我通过更改构建解决了这个问题,这样绝对路径就不会进入有问题的动态库文件(libquazip)。我仍然使用install_name_tool删除Qt安装的绝对路径。然后,我使用macdeployqt创建捆绑包,对捆绑包签名并创建DMG文件
    方弘
    2023-03-14

    很抱歉回答我自己的问题,但我看不到其他方法,因为编辑原始问题会导致意大利面条文本。

    我终于解决了我的问题。首先是功劳:(1)我的另一个stackoverflow问题的答案非常有用,(2)我从苹果官方开发者那里得到了非常好的(付费)建议,通过提交所谓的技术支持事件(TSI)。

    基于所有这些,我现在可以在这里给出一个非常简洁的配方,说明如何让你的Mac应用程序成功地被GateKeeper处理。在详细说明配方后,我将说明我最初的错误是什么。

    目标:在Xcode之外开发了一个Mac应用程序,让GateKeeper发出警告“从互联网上下载......”有三个按钮,其中一个是“打开”。

    失败:当网关守护设备发出警告时..身份不明的开发商..”或文本”..未经证实的开发商..”在这两种情况下,消息框都只有一个OK按钮。

    让您的应用看门人就绪包括三个步骤:

      < li >使您的应用程序独立,没有不可接受的外部依赖性。唯一可接受的外部依赖是系统库。所有其他依赖项应该已经复制到您的MyApp.app文件夹中。网关守护设备拒绝任何具有非系统外部依赖性的应用程序 < li >二进制文件不应位于MyApp.app文件夹中的非法位置。库放在MyApp/Contents/Frameworks中,可执行文件放在MyApp/Contents/MacOS中 < li > All中的所有二进制文件都应该经过数字签名。然后MyApp.app文件夹要签名。对于此次签署,苹果公司“开发者ID申请…”证书是必需的

    我们的食谱是自动的。所有的工作都由一个脚本完成。对于Qt Creator,我们使用qmake脚本,通过< code>$$system命令访问系统外壳。当使用(Xcode)系统命令< code>codesign、< code>spctl或< code>check-signature时,我们假设您已经将stderr重定向到stdout,如问题答案中所述。否则,在运行这些实用程序时,您将无法捕捉系统响应。在下文中,我们不会明确显示这种重定向。

    这是我们的食谱

    A. 使应用独立:

    1. (使用脚本)将所有需要的二进制文件复制到MyApp.folder
    2. 运行(使用脚本)install_name_tool-changeinstall_name_tool-id使得应用内的所有依赖项都是相对类型@executable_path/.../MacOS...or@executable_path/... /Frameworks
    3. (使用脚本)在MyApp.app文件夹内的所有二进制文件上运行otool-L并标记任何非法依赖项,例如“@rpath...”或绝对文件路径不是系统路径。请注意,otool-L不能保证找到所有依赖项。插件通常超出otool的范围。这就是为什么您需要下一次检查。
    4. 在“MyApp.app/Contents/MacOS”位置启动终端。运行exportDYLD_PRINT_LIBRARIES=1。然后在同一个终端窗口内运行。 /MyApp。您的终端将充满超过一百个加载的库。再次检查此列表以查找禁止的库(库存在于您的计算机上,但不存在于您客户的计算机上)。
    5. 吃布丁的证据。我们使用MacInCloud虚拟机并检查我们的应用程序是否在那里运行。替代解决方案可能是不是开发人员的亲戚的Mac。或者您也可以在自己的Mac上创建一个新用户(“测试”)并将应用程序复制到其下载(或桌面文件夹,或...)。在后一种情况下,您必须临时重命名IDE的根文件夹,否则用户“测试”将在那里找到丢失的二进制文件。

    B 对应用进行签名

    C 外部检查

    将应用压缩到单个zip文件中。上传到您的云服务器之一

    守门人在其一般守门人角色上保留一长串(通常有数百项)异常。如果您想测试GateKeeper,则您的应用程序不得在该列表中。与编辑此列表相比,更简单的技巧是在Mac上创建新用户。登录该用户并从Internet云服务器下载zip文件。Finder将自动解压缩它。点击它。如果GateKeeper告诉你它可以打开应用程序,但同时警告你它是从互联网下载的,那么是时候喝杯(白)啤酒了。

    我的错误

    我做了大量的安装和签名工作,但没有明确检查每个二进制文件的结果。之后,我会在许多二进制文件上使用< code>otool -L,但不是在所有文件上。我忽略了一个事实,从早期的Qt版本升级到Qt 5.5,二进制文件< code>libqminimal.dylib获得了一个额外的依赖项,即。:< code>QtDBus。我没有注意到,但是看门人注意到了。

    Qt开发人员可能会想知道为什么我们不只是使用mac部署yqt在Mac上部署Qt应用程序。首先,我们不喜欢不使用记录不良的黑盒实用程序。在Internet论坛上,有相当多的人报告了mac部署yqt的问题。此外,在比较不同的Qt版本时,Qt库可以有不同的安装位置(由otol-L报告)。当我们有一个新的Qt版本时,我们的脚本将立即开始大喊禁止的依赖项。通过这种方式,我们获得有关新版本中发生了什么变化的信息。

     类似资料:
    • 首先,虽然我关注StackOverflow已经有相当一段时间了,但这是我第一次发布一些东西,所以如果我做错了或者不按规则做的话,请随时为我指出正确的方向。 我正在开发一个PDF数字签名应用程序,使用iText5,它依赖于一个外部服务,在我准备好PDF签名后提供一个签名哈希。 如iText文档中所述,在第一阶段,我准备了PDF(在最终实现中,所有PDF都可能是多签名的,因此我使用追加模式),如下所示

    • 我正在尝试用DSS签署PDF文档,我的问题是我无法在服务器a中计算文档的哈希值,然后在服务器B中签署它。 知道服务器A包含PDF文档,我们在服务器B中检索用于签名的证书 我的问题是如何在不需要证书的情况下计算服务器a中文档的哈希值。然后在服务器B上发送签名? 更新: ******散列的准备和计算******** ******散列签名******** ********PDF错误:*********

    • 有没有办法使用openssl对x509证书或任何文档进行数字签名?

    • 您好,我可以使用iText 5对PDF文档进行数字签名。我需要再次签署PDF,而在验证PDF时,它表明初始签名无效。您可以在此处查看再次签名的文件。 请参见下面用于标记的代码, 请让我知道出了什么问题。

    • 我已经创建了一个java应用程序,并按照以下教程将其与一个jre捆绑并转换为。app包:https://www.jemchicomac.com/signing-a-sandbox-app-in-osx/http://speling.shemnon.com/blog/2014/04/10/getting-your-java-app-in-the-mac-app-store/ 我可以创建。应用程序包成

    • 问题内容: 如何使用iText签名pdf?我正在通过此LINK进行操作, 但不了解my_private_key.pfx。我真的需要数字签名证书吗?请澄清一下。提前致谢。 问题答案: 您在问题中提到的文档很好。您必须创建数字签名文件。 该链接具有使用PKCS文件和签署PDF文档的工具。它声称使用iText,因此您应该能够理解这些步骤。源代码在这里