【问题标题】:Signing OS X app on Windows (without codesign)在 Windows 上签署 OS X 应用程序(无代码设计)
【发布时间】:2014-06-16 09:24:55
【问题描述】:

我有可以在 Wine 下的 OS X 上运行的 Windows 应用程序。为方便起见,我想将应用程序打包为 OS X 应用程序(基于 WineBottler 的 xxx.app 文件夹的 ZIP 存档)。

请注意,应用程序的主要可执行文件(由Info.plistCFBundleExecutable 标记定义)是一个shell 脚本,而不是二进制文件。

我想签署应用程序以通过 OS X Gatekeeper。由于我的完整构建过程在 Windows 上运行(实际上我根本没有 Mac),因此我需要在 Windows 上对其进行签名。

我已经发现签署应用程序会创建包含四个文件的 _CodeSignature 文件夹:

CodeDirectory
CodeRequirements
CodeResources
CodeSignature

我没有找到任何描述这些文件内容的规范。

在实验中,我发现CodeResources 是一个 XML 文件,其中包含应用程序中所有文件的 SHA-1 哈希值。我可以生成它。

CodeRequirements 二进制文件的内容似乎已修复。它似乎不会随着应用程序的内容而改变。确认表示赞赏。这个文件有什么用?

至于二进制文件CodeDirectoryCodeSignature 我不知道。

这两个文件都会随着应用内容的变化而变化。似乎任何应用程序文件更改(包括纯文本许可文件)都会影响它们。

CodeSignature 显然包含签名。我可以在文件中看到有关代码签名证书的纯文本信息。有没有可以生成文件的工具?因为它是一个签名,它应该是相当标准的。尽管可能有一些额外的二进制元数据会使生成更加困难。有谁知道它具体是什么标志?我可以想象它只签署CodeResources 文件,因为它描述了应用程序中的所有其他文件。还是它实际上递归地签署了应用程序中的所有文件?

本机 OS X 应用程序只有 CodeResources。所以_CodeSignature 中实际上没有签名。我想这是因为它们在主可执行二进制文件中嵌入了签名。请注意,我的 [Windows] 二进制文件(尽管上面提到的 Info.plist 没有直接引用它)是使用 Windows signtool.exe 进行代码签名的。显然,即使没有引用,OS X 也能识别签名,因为 codesign -d -vvv xxx.app 输出包含有关证书的信息:

Executable=/Applications/WinSCP.app/Contents/MacOS/startwine
Identifier=WinSCP
Format=bundle with generic
CodeDirectory v=20100 size=135 flags=0x0(none) hashes=1+3 location=embedded
Hash type=sha1 size=20
CDHash=a1ef4f04b2c1b4b793788ce3ab9d7881528f3d95
Signature size=4867
Authority=Martin Prikryl
Authority=VeriSign Class 3 Code Signing 2010 CA
Authority=VeriSign Class 3 Public Primary Certification Authority - G5
Signed Time=23.4.2014 23:51:18
Info.plist entries=14
Sealed Resources version=2 rules=12 files=846
Internal requirements count=2 size=136

令人困惑的是根本没有提到二进制名称。无论如何,它不会让 Gatekeeper 高兴。请注意,上面的测试是针对已经包含 CodeResources 文件的应用程序运行的(这可能是 Sealed Resources version 也称为 rulesfiles 计数与文件内容匹配)。

【问题讨论】:

  • 二进制是 Mach-O 格式吗?
  • 您是否阅读过 Apple 的代码签名指南 (developer.apple.com/library/mac/documentation/security/…)?它至少回答了你的一些问题。
  • @danilev 感谢您的链接。我以前确实看过它,但现在再次仔细阅读它。它证实了我的假设,即CodeRequirements 不是签名的一部分,我应该主要关注CodeDirectoryCodeSignature。不幸的是,没有关于它们的结构的描述。
  • 顺便说一下,codesign 实用程序和 codesigning 库源代码是开放且可用的:opensource.apple.com/source/security_systemkeychain/… - opensource.apple.com/source/libsecurity_codesigning。它以前曾尝试过,但我认为它从未在非 Mac 平台上编译过。但是,如果您仔细阅读源代码,您可能会在那里找到有用的信息。
  • 查看isign,它是codesign的python实现

标签: xcode macos code-signing codesign code-signing-certificate


【解决方案1】:

我们尝试使用libsecurity_codesigning 库的源代码对代码签名进行逆向工程。虽然看起来可行,但还是太费劲了,所以我们考虑放弃。我们至少愿意分享我们迄今为止的发现,以便其他人可以借鉴。

我们发现当codesign 找不到MachO 二进制文件时,它会退回到SecCodeSigner::Signer::signArchitectureAgnostic 中实现的“架构无关”签名。

那里的关键步骤:

  • CodeDirectory 文件生成。除了文件头(包括目录版本)外,该目录还包括捆绑包的各个部分的少量 SHA-1 哈希
  • CodeSignature 文件生成。签名使用加密消息语法 (CMS) 格式对 CodeDirectory 文件进行签名。可以使用 OpenSSL 在任何平台上验证签名:

    openssl cms -verify -in CodeSignature -inform DER
        -content CodeDirectory -noverify -out CodeDirectory.verified
    

    请注意,需要 -noverify 跳过证书验证,因为 OpenSSL 似乎不支持证书的“代码签名”目的。

    OpenSSL 应该能够使用以下命令创建 CMS 签名:

    openssl cms -sign -in CodeDirectory -out CodeSignature 
        -signer certificate.pem -outform DER
    

    但是 OS X 不接受这样的签名。

我们没有进一步了解。

【讨论】:

  • 嗨,只是想知道你是否在这方面取得了更多进展......我正在尝试使用 openssl 在 linux 服务器上为 macho 文件构建签名验证器。验证 CMS 签名链是一回事, 但我正在努力找出如何验证文件内容哈希(macho 文件的哪些部分与 CodeDirectory 中的哈希值相关。也许你知道如何计算它们?谢谢!
【解决方案2】:

不严格在 Windows 上签名,但您是否考虑过将远程桌面变成朋友的 Mac 或在云端租用 Mac? http://www.macincloud.com 似乎有相当合理的计划。

可以省去很多麻烦。您真正需要访问的是协同设计工具和终端。

编辑:您仍然需要一个 Apple 开发者帐户来签署应用程序 - Gatekeeper 只允许来自 Apple 颁发的开发者 ID 证书的签名。

【讨论】:

  • 感谢您的建议。我也在考虑这种方法。请注意,您不需要 Apple 颁发的证书。我能够使用codesign 对应用程序进行签名,即使我拥有用于​​签署 Windows 8 应用商店应用程序的 VeriSign 证书。看门人也很高兴。
  • 有没有人为此成功使用过 MacinCloud?我刚刚注意到他们有一个 1 美元/小时的预付费计划,这似乎非常适合不频繁、短时间的使用。
猜你喜欢
  • 2017-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-28
  • 1970-01-01
  • 1970-01-01
  • 2014-01-26
  • 1970-01-01
相关资源
最近更新 更多