我开发了一个带有Qt5的Mac应用,所以在Xcode之外 . 我希望GateKeeper允许我的应用程序在客户端的计算机上运行,而不是发出“无法打开,因为无法确认开发人员的身份”警告 .
我已成功对该应用程序进行了数字签名,但GateKeeper仍然附带此投诉 . 我有一个Apple开发人员证书(我是团队代理),我的钥匙串说它是有效的 . 我还安装了两个Apple根证书 .
我使用命令行实用程序 codesign
对app文件夹中的所有二进制文件进行数字签名,此外我还对app文件夹本身进行了数字签名 . 在所有情况下,协同设计的响应都是提供信息的,并且不会显示错误 . 使用codesign我可以检查确实所有二进制文件都已签名,正在运行
$ codesign --verify --deep --verbose=2 MyApp.app
显示所有二进制文件都已验证 . 此外,它报告:
MyApp.app:在磁盘上有效MyApp.app:满足其指定要求
运行:
$ codesign -v --verbose=4 --display MyApp.app
给
可执行= /用户/ XXX /中继/ YYY /部署/释放/ MyApp.app /内容/ MacOS的/ MyApp的标识符= aaaa.MyApp格式=马赫-O薄(x86_64的)CodeDirectory v捆绑= 20200大小= 12461个标志=为0x0(无)散列= 616 3位置=嵌入式哈希类型= SHA1大小= 20 CDHash = d1c12c783dac0e8d9a2b749fb896b11558cec8b6签名大小= 8532管理局=开发者ID的应用:XXXXX管理局=开发者ID的认证中心局=苹果根CA时间戳= 7月29日2015 12; 04:40 Info.plist entries = 8 TeamIdentifier = YYYYY Sealed Resources version = 2 rules = 12 files = 10内部要求count = 1 size = 180
这似乎没问题 .
运行
$ spctl -a -t exec -vv MyApp.app
在所有二进制文件上给出结果
MyApp.app:已接受来源=开发者ID来源=开发者ID应用程序:XXXX
这也似乎没问题
在应用程序或app文件夹内的二进制文件上运行XCode命令行工具检查签名:
$ ./check-signature /Users/xxx/trunk/yyy/release/MyApp.app
给出结果
(c)2014 Apple Inc.保留所有权利 . 是
在所有情况下都是理想的结果 .
但GateKeeper仍然不接受该应用程序,并抱怨开发人员无法确认 .
[added by author on Friday July 17, 2015]
我想我已经找到了问题 . 我不知道它是一个功能还是一个OSX错误 . stackoverflow question 19551298给了我很多帮助 .
每当从互联网上下载文件时,它都会获得与之关联的扩展文件属性com.apple.quarantine . 在Finder中双击此下载文件时,GateKeeper有两种可能:
-
当文件未签名时,它会发出“Unidentified developer etc”消息
-
当文件经过数字签名时,它会发出“开发人员无法确认等”消息
在这两种情况下,MessageBox只有一个按钮,一个OK按钮 . 单击此按钮时,除了MessageBox关闭之外没有任何反应 .
如果删除了扩展属性(xattr -d),应用程序将运行,是否已签名 .
通过在应用程序上的Finder中单击鼠标右键然后单击“打开”菜单操作启动应用程序时,行为会有所不同 . 再次显示了两个消息框中的一个,但现在有一个额外的按钮,允许用户打开应用程序 . 签名和未签名之间的唯一区别是“未识别”或“未确认”消息 . 我不希望我的客户能够分辨出差异 . 因此签署应用程序是徒劳的 .
论Apple Support Documentation我预期的另一个基础,把关更漂亮行为时,双击下载的应用程序(可能是文件已经过时,还是我看错了):
-
如果应用程序已签名,GateKeeper应显示一个MessageBox,其中包含“从Internet上下载等”和一个“仍然继续进行”的按钮?
-
如果应用程序未使用单个“确定”按钮和“未识别的开发人员等”文本对MessageBox进行签名 .
4 回答
adlag的问题和自我回答对帮助我克服同样的问题非常宝贵 . 然而,和他的食谱一样好,有些陈述不太正确,所以我想提供一些额外的观点 .
没有必要用@executable_path语句替换二进制文件和动态库中的@rpath条目 . 只要嵌入在二进制文件中的实际rpath条目不是绝对的,@rpath语句就可以了 . 您可以找到许多使用rpath的有效Qt应用程序包 . 你可以按照adlag的说法开展工作,但你可能正在为自己工作 .
请参阅上面的jil评论,了解如何使用
otool -l $file | grep -A2 LC_RPATH
和install_name_tool -delete_rpath $path $file
来检查和删除二进制文件和库中的嵌入路径请参阅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
不要在dylib文件上运行
spctl -a -t exec -vv /path/to/binary
. 你会得到关于的错误资源包络 . 这是预期的,而不是问题 .根据我的经验,
macdeployqt
工作正常 . 我通过更改构建来解决问题,这样绝对路径没有进入有问题的dylib文件(libquazip) . 我仍然使用install_name_tool
删除Qt安装的绝对路径 . 然后我使用macdeployqt
创建捆绑包,签署捆绑包并创建DMG文件 .经过多次尝试后想出了问题 .
在我的情况下:流行消息 - 损坏的应用程序是由于库缺失 . 我使用QT创建了.app文件 . 要生成dmg,我使用的是deploymacqt命令工具 . deploymacqt工具在.app中创建动态库,所以基本上如果我们在创建dmg之前进行协同编码,这个alter会操纵代码符号 . 所以正确的解决方法是 .
一旦完成这些操作,您将看不到弹出消息,说应用已损坏或损坏或未识别的开发人员 .
很抱歉回答我自己的问题,但我没有别的办法,因为编辑原始问题会导致意大利面条文字 .
我终于解决了我的问题 . 首先是信用:(i)我的其他stackoverflow question的答案非常有用,(ii)我通过提交所谓的技术支持事件(TSI)得到了Apple官方开发人员的非常好(付费)的建议 .
基于这一切,我现在能够在这里给出一个非常简洁的方法,说明如何通过GateKeeper成功处理您的Mac应用程序 . 在详细说明食谱后,我将展示我原来的错误 .
获取应用程序GateKeeper就绪包括三个步骤:
我们的食谱是自动的 . 所有工作都由一个脚本完成 . 在Qt Creator的情况下,我们使用qmake脚本,我们通过
$$system
命令访问系统shell . 使用answer to question中概述的(Xcode)系统命令codesign
,spctl
或check-signature
we assume you have redirected stderr to stdout 时 . 否则,在运行这些实用程序时,您将无法捕获系统响应 . 在下文中,我们不会明确显示此重定向 .HERE IS OUR RECIPE
这里是所需的GateKeeper警告:
My mistake
我做了大量的安装和签名,没有明确检查每个二进制文件的结果 . 之后我会在一些二进制文件上使用
otool -L
但不是全部 . 我错过了从早期的Qt版本升级到Qt 5.5的事实,二进制libqminimal.dylib
已经获得了额外的依赖,即:QtDBus
. 我没有注意到它,但GateKeeper做到了 .Qt开发人员可能想知道为什么我们不只是使用
macdeployqt
在Mac上部署Qt应用程序 . 首先,我们不喜欢不使用记录不明的黑盒实用程序 . 在互联网论坛上,有很多人报告macdeployqt
的问题 . 此外,在比较不同的Qt版本时,Qt库可以具有不同的安装位置(由otool-L
报告) . 当我们有一个新的Qt版本时,我们的脚本将立即开始对禁止的依赖关系大喊大叫 . 通过这种方式,我们可以获得有关此新版本中已更改内容的信息 .我的两位:
如果您的应用程序已正确签名,您应该会看到一个带有“打开”按钮的系统对话框 .
我通过查看从互联网上下载的另一个.app找到了隔离属性的值 . 我不知道这个 Value 意味着什么 .
我真的不明白为什么spctl命令说“已接受”,即使Gatekeeper服务拒绝打开应用程序 .