Apple 的协同设计实用程序如何决定使用哪种 SHA 算法对共享库进行签名?



首先,一个小背景:我正在调查为什么我公司的MacOS/X应用程序(所有帐户都认为它是正确签名的;它在MacOS/X 10.11.X和10.12.X下运行良好;Gatekeeper在所有MacOS版本上都很好;"spctl-assessment"one_answers"codesign-vvv"都说它满足所有操作系统版本的要求)在我尝试时不会在OS/X 10.10.X下启动为了启动它,我收到了一份崩溃报告,dyld抱怨一些库没有正确签名:

Dyld Error Message:
Library not loaded:     @executable_path/../Frameworks/libcrypto.1.0.0.dylib
Referenced from: /Applications/MyApplication v123/MyApplication.app/Contents/MacOS/MyApplication
Reason: no suitable image found.  Did find:
/Applications/MyApplication v123/MyApplication.app/Contents/MacOS/../Frameworks/libcrypto.1.0.0.dylib: code signature invalid for '/Applications/MyApplication v123/MyApplication.app/Contents/MacOS/../Frameworks/libcrypto.1.0.0.dylib'

在调查这个问题时,我注意到.app/Contents/Framework中的库——它们都是使用完全相同的代码签名命令,通过运行OS/X 10.12的OS/X构建机器上的构建/包脚本进行签名的——有不同类型的哈希计算。

也就是说,如果我看看其中一个非Qt.dylib文件是如何签名的,我会发现它只记录了一个sha256哈希:

sierrabuild-polaris:MyApp v123 autobuild$ codesign -vvvd ./MyApp.app/Contents/Frameworks/libsndfile.1.dylib 
Executable=/Applications/MyApp v123/MyApp.app/Contents/Frameworks/libsndfile.1.dylib
Identifier=libsndfile.1
Format=Mach-O thin (x86_64)
CodeDirectory v=20200 size=4140 flags=0x0(none) hashes=125+2 location=embedded
Hash type=sha256 size=32
CandidateCDHash sha256=b4256e9bf0fac567bb8ac86f56964c066b93d069
Hash choices=sha256     <----------------------------- ONLY 256!?
CDHash=b4256e9bf0fac567bb8ac86f56964c066b93d069
Signature size=8846
Authority=Developer ID Application: MyCompany
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=Jan 24, 2017, 1:39:58 AM
Info.plist=not bound
TeamIdentifier=5XD27G7646
Sealed Resources=none
Internal requirements count=1 size=172

但是,如果我看看任何一个被捕获的Qt框架是如何签署的,OTOH,我会发现它包含了sha1和sha256哈希:

sierrabuild-polaris:MyApp v123 autobuild$ codesign -vvvd ./MyApp.app/Contents/Frameworks/QtCore.framework/Versions/5/QtCore
Executable=/Applications/MyApp v123/MyApp.app/Contents/Frameworks/QtCore.framework/Versions/5/QtCore
Identifier=org.qt-project.QtCore
Format=bundle with Mach-O thin (x86_64)
CodeDirectory v=20200 size=42549 flags=0x0(none) hashes=1324+3 location=embedded
Hash type=sha256 size=32
CandidateCDHash sha1=09b5854f83091228f1baaad1455e7a30d6500c95
CandidateCDHash sha256=6dfdc74da06618e1b406a6e5fd0794fe43701def
Hash choices=sha1,sha256    <------------- BOTH sha1 and sha256, yay!
CDHash=6dfdc74da06618e1b406a6e5fd0794fe43701def
Signature size=8896
Authority=Developer ID Application: MyCompany
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=Jan 24, 2017, 1:39:57 AM
Info.plist entries=8
TeamIdentifier=5XD27G7646
Sealed Resources version=2 rules=13 files=1
Internal requirements count=1 size=184

考虑到dyld在Yosemite下运行我的应用程序时的错误总是指向一个只有sha256哈希的库,我的工作理论是,OS/X 10.10.X的dyld足够古老,它不知道SHA-256哈希,这就是为什么当它试图加载一个只使用SHA-256散列签名的捕获共享库时出错的原因。

我的问题(假设我在这里没有完全弄错树)是:代码签名如何决定何时单独用sha256哈希标记文件,而不是同时添加sha1和sha256哈希?我如何强制代码设计始终包含这两个哈希,以便我的应用程序能够再次在10.10.x下启动(就像我们将构建机器升级到OSX/Sierra之前一样)?

记录在案,以下是我在构建脚本中调用代码签名的方式——所有库的调用参数完全相同(最终为sha1、sha256的Qt框架库和最终仅为sha256的非Qt库),例如:

codesign -f -v -s "Developer ID Application:  MyCompanyName" "./Frameworks/libcrypto.1.0.0.dylib"
codesign -f -v -s "Developer ID Application:  MyCompanyName" "./Frameworks/QtCore.framework/Versions/5/QtCore"

经过大量的谷歌搜索,这个答案和这个答案让我找到了解决方案。

问题是,我的应用程序中包含的几个第三方共享库只是使用它们的默认构建设置(例如"./configure;make")进行编译的,而且由于它们是在OS/X 10.12下编译的,所以编译时自然只考虑了10.12的兼容性。

为了让它们以这样一种方式编译,即生成的.dlib文件也适用于早期的OS/X版本,我在构建脚本的顶部添加了以下几行:

export  LDFLAGS="-mmacosx-version-min=10.9"   
export   CFLAGS="-mmacosx-version-min=10.9"   
export CXXFLAGS="-mmacosx-version-min=10.9"

这对除了libssl之外的所有库(libssh2、libsndfile、libogg、libflac、libvorbis等)都起到了作用——对于那个库,我必须手动修改Configure文件,并以这种方式将-mmacosx version min参数插入编译器的命令行参数中。

有了这一更改,codesign现在将SHA-1和SHA-256哈希应用于所有.dlib文件,生成的.app现在可以在10.10.x下正常运行。

Jeremy Friesner的回答对我很有效。只是关于编译OpenSSL的一个附带说明。至少在1.0.2小时内,不需要更改配置文件。以下操作很好

./configure darwin64-x86_64-cc shared --openssldir=$HOME/cmake_builds/openssl-1.0.2h.bin -mmacosx-version-min=10.10

只有当您的目标是macOS 10.14或更高版本时,它才会停止使用SHA-1。

设置MACOSX_DEPLOYMENT_TARGET = 10.14对我有用(需要设置为用于在Xcode之外构建和链接的环境变量,并且可以在Xcode的目标配置中为Xcode本身设置)。

最新更新