macos - Apple 的 codesign 实用程序如何决定使用哪种 SHA 算法对共享库进行签名?

标签 macos sha codesign

首先,一点背景知识:我正在调查为什么我公司的 MacOS/X 应用程序(所有帐户似乎都正确签名;它在 MacOS/X 10.11.x 和 10.12.x 下运行良好;Gatekeeper 对所有应用程序都很好MacOS 版本;“spctl --assess”和“codesign -vvvv”都说它满足其对所有操作系统版本的要求)但是不会在 OS/X 10.10.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 中的库——它们都使用完全相同的 codesign 命令进行签名,通过我们运行 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

鉴于尝试在 Yosemite 下运行我的应用程序时 dyld 的错误总是指的是只有 sha256 哈希的库之一,我的工作理论是 OS/X 10.10.x 的 dyld 足够古老,它不知道 SHA- 256 哈希,这就是为什么它在尝试加载仅使用 SHA-256 哈希签名的俘虏共享库时出错的原因。

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

作为记录,以下是我在构建脚本中调用 codesign 的方式——所有库的调用参数完全相同(以 sha1、sha256 结尾的 Qt 框架库和以 sha1、sha256 结尾的非 Qt 库只有 sha256),例如:
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"

最佳答案

经过大量的谷歌搜索,this answerthis answer引导我找到解决方案。

问题是我的应用程序中包含的几个第三方共享库仅使用其默认build设置(例如“./configure; make”)进行编译,并且由于它们是在 OS/X 10.12 下编译的,因此它们很自然地编译时只考虑了 10.12 兼容性。

为了让它们以这样一种方式编译,即生成的 .dylib 文件也适用于早期的 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 等)都有效——对于那个,我必须手动修改配置文件并插入 -mmacosx- version-min 参数以这种方式进入编译器的命令行参数。

通过这一更改,codesign 现在将 SHA-1 和 SHA-256 哈希应用于所有 .dylib 文件,生成的 .app 现在在 10.10.x 下按预期运行。

关于macos - Apple 的 codesign 实用程序如何决定使用哪种 SHA 算法对共享库进行签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41865537/

相关文章:

git - 为什么 Git 不使用更现代的 SHA?

iOS 和 RESTful 网络服务加密

xcode - Codesign 想要访问钥匙串(keychain)中的 key "access",我输入了登录密码,但一直询问我

iphone - 我的一位 friend 想使用我的开发者帐户来提交应用

mysql - 在 OS X 上安装 RMySQL 时出错

cocoa - Cocoa (Mac) 应用程序的广告框架?

java - 安装了 JRE 后无法打开 JAR 文件?

objective-c - 如何在 osx 中的 NSDatePicker 对象上设置当前日期

encryption - SHA1 与 RSA : what's the difference between them?

ios - 代码设计错误 - SecKey API 返回 : -67671