当前位置: 首页 > 科技观察

通过开源、多平台代码签名扩展Apple生态系统访问

时间:2023-03-21 22:28:22 科技观察

Apple运行着一些现有的最大和最赚钱的软件应用程序生态系统。从理论上讲,访问这些生态系统传统上需要macOS和AppleDeveloperProgram的会员资格。如果你想为苹果操作系统开发应用程序,你很可能会使用苹果操作系统和苹果官方工具进行开发和发布。但对于开源开发人员来说,通常希望以最小的努力分发跨平台应用程序。在整个编程语言生态系统中,你运行的操作系统被抽象成许多应用程序的实现细节。通过创建macOS、iOS等开发需要直接访问macOS和通常高于市场价格的Apple硬件的要求,Apple软件生态系统强加的分发要求实际上是排他性的,并阻止感兴趣的各方进入其生态系统。在Apple平台上分发软件的问题之一是代码签名和公证,即您需要:1.在应用程序中嵌入加密签名,有效地证明来自与AppleDeveloperProgram关联的帐户的真实性。(这是签名。)2.将您的应用程序上传到Apple,以便他们检查它,验证它是否符合要求,并可能存储一份副本。Apple然后发布自己的加密签名,这是一个经过公证的证书,然后需要将其嵌入到正在分发的应用程序中,以便Apple的操作系统可以信任它。(这是公证。)从历史上看,这些步骤要求Apple专有软件只能从macOS运行。这意味着,即使您处于Rust、Go等软件生态系统中,或者您可以在不直接访问macOS的情况下交叉编译应用程序的Web平台(测试显然是另一回事),您仍然需要macOS对您的应用程序进行签名和公证.由于默认安全设置,macOS需要有效的签名和公证。在iOS等移动平台上,除非您运行的是越狱设备,否则无法分发未签名和经过公证的应用程序。如果我不需要macOS来构建我的应用程序,为什么我必须在我的软件发布过程中使用Apple设备?为什么签发申请的时候要签字公证,不能更精简一点吗?如果可以重新实现Apple代码签名,这样开发人员就有更多的灵活性和机会将他们的应用程序分发到Apple的生态系统中,那就太好了。它的最终目标是将Apple生态系统扩展到更多开发者。首先,感谢rcodesign0.14.0的发布。这是我第一次发布rcodesign的预构建二进制文件(Linux、Windows和macOS)。macOSrcodesign可执行文件是自签名的,由GitHubActionsLinux运行器使用YubiKey的唯一代码签名证书签名。2021年,apple-codesign项目/Rustcrate变化很大!只需查看变更日志!该项目已从tugger-apple-codesign重命名。如果你通过cargoinstall安装,你需要cargoinstall--forceapple-codesign来强制Cargo用另一个箱子中的一个覆盖rcodesign可执行文件。rcodesignCLI可执行文件仍然存在,并且比以往任何时候都更强大。您仍然可以在Linux、Windows、macOS和任何其他可以编译Rust程序的平台上签署Apple应用程序。Sphinx文档在这里,它与PyOxidizer的文档一起发布在readthedocs.io上(因为我使用的是monorepo)。那里有一些通用文档,例如有关如何通过将您自己的替代代码签名PKI部署到并行Apple来选择性地绕过Gatekeeper的指南。支持签名包、DMG和.pkg安装程序当我去年宣布该项目时,只有Mach-O二进制文件和非常简单的.app包是可签名的。尽管如此,还是有很多微妙之处。Rcodesignsign现在可以签署更复杂的包,包括许多嵌套包。有报告称iOS应用程序包已正确签名。该工具还支持签名的.dmg磁盘映像文件和.pkg扁平包安装程序。已知的签名限制现在记录在Sphinx文档中。我相信rcodesign现在支持对用于Apple软件分发的所有主要文件格式进行签名。支持在Linux、Windows和macOS上进行公证Apple发布了一个名为Transporter的Java工具,允许您将工件上传到Apple进行公证。他们使这个工具可用于Linux、Windows,当然还有macOS。虽然这个工具不是开源的,但是使用这个工具可以让你在Linux和Windows上进行公证,同时仍然使用Apple的官方工具与他们的服务器进行通信。rcodesign现在支持调用Transporter并将工件上传到Apple进行公证。我们现在支持公证包、.dmg磁盘映像和.pkg扁平安装程序包。我已经成功地公证了所有这些来自Linux的应用程序类型。通过支持所有应用程序类型的签名和公证,现在可以在没有macOS参与发布过程的情况下发布Apple软件。YubiKey集成我尝试尽可能多地使用我的YubiKey,因为存储在YubiKey上的密钥或私钥可能比位于某个文件系统中的密钥或私钥更安全。如果你破解我的设备,你很可能可以访问我的私钥。但是你需要物理访问我的YubiKey并胁迫或胁迫我解锁它才能访问它的私钥。rcodesign现在支持使用YubiKeys进行签名操作。这确实需要默认的智能卡Cargo功能。因此,如果手动构建,您将需要例如cargoinstall--featuressmartcardapple-codesign。YubiKey集成来自yubikey。这个crate将直接与macOS和Windows中内置的智能卡API对话。所以如果你有一个启用了YubiKey支持的rcodesign构建,YubiKeys应该可以工作。通过插入YubiKey并运行rcodesignsmartcard-scan来尝试一下。可以在此处查看YubiKey集成文档。我什至实现了一些命令来轻松管理YubiKey上的代码签名证书。例如,您可以直接在设备上运行rcodesignsmartcard-generate-key--smartcard-slot9c来生成新的私钥,然后rcodesigngenerate-certificate-signing-request--smartcard-slot9c--csr-pem-路径csr.pem将该证书导出到证书签名请求(CSR),您可以用它交换Applie在developer.apple.com上颁发的签名证书。这意味着您可以轻松创建代码签名证书,其私钥直接在硬件设备上生成且永远无法导出。以这种方式生成密钥比将它们存储在软件存储库(例如Apple的Keychains)中更安全。远程代码签名我最感兴趣的功能是我所说的远程代码签名。我在GitHub托管的LinuxGitHubActions运行器上签署了一个macOSUniversalMach-O可执行文件,使用YubiKey物理连接到我桌子旁边的Windows11设备。签名的应用程序不会在计算机之间复制。我有一个调用rcodesignsign--remote-signer的GitHubActions工作流程。我手动触发了工作流程并开始使用浏览器观看近乎实时的作业输出。rcodesignsign--remote-signer打印出一些指令(包括一堵base64编码数据)来指示下一步要做什么。重要的是,它需要其他人运行rcodesignremote-sign才能继续签名过程。日志向我们展示了YubiKey的连接和身份验证,以及与远程服务器对话的一些状态更新。远程签名使我能够从GitHub运营的GitHubActionsrunner对macOS应用程序进行签名,同时使用安全存储在我的YubiKey上的代码签名证书,该证书插入到距离GitHubActionsrunner数百公里的Windows设备上。这里发生的是2个rcodesign进程通过中央中继服务器桥接的websockets相互通信。我免费运营一个默认服务器。服务器是开源的,如果你想运行你自己的服务器,你可以使用terrform模块,希望它只需要几分钟。当发起设备希望创建签名时,它会向签名者发送一条消息,请求加密签名。然后将签名发回给合并它的发起者。我在设计此功能时考虑了CI系统(如GitHubActions)的自动发布。我想要一种方法来简化我的应用程序的代码签名和发布过程,而不必让CI中的低信任设备无限制地访问我的私有签名密钥。这在许多其他情况下可能很有用。您是否曾经因为没有Apple颁发的代码签名证书而通过电子邮件或将应用程序发送给其他人进行签名?现在您有了不需要复制文件的替代解决方案。只要您可以看到启动设备的日志输出,或者将输出传送给您(例如通过聊天应用程序或电子邮件),您就可以在另一台设备上远程签署文件!关于通过第三方运营的中央服务器远程签名的安全Websockets?!授予远程设备对任意内容进行代码签名的权限?!你的恐惧和怀疑是100%合理的:我也会!促进远程代码签名的服务可能是一个非常有利可图的攻击目标,如果被滥用,它可能会被用来迫使使用有效代码签名证书的各方签署不需要的代码,例如恶意软件。有很多很多错误的方法可以实现这样的目标。远程代码签名设计和安全注意事项包含我的一些高级设计目标和安全评估。RemoteCodeSigningProtocol详细介绍了通信协议,包括涉及的加密(实际加密,不是流行的加密)。关键是协议和服务器的设计使得恶意服务器或中间人无法伪造签名请求。签名会话会在几分钟后过期,第三方或服务器无法注入会导致不需要的签名的恶意消息。会话临时共享加密密钥是通过初始握手获得的,并从那里使用对称加密密钥,因此对等点之间所有有意义的消息都是端到端加密的。恶意服务器能做的最糟糕的事情就是拒绝服务。我相信我的远程签名实施比当今许多需要复制私钥并让低信任设备(如CI工作者)访问它们或在没有加密监管链的情况下复制文件的常见做法更安全篡改。是的,远程签名引入了使用签名密钥进行远程访问的载体。但按照我的意愿进行实践,远程签名可以消除复制私钥或授予对私钥的无限制访问的需要。从威胁建模的角度来看,我认为密钥访问中的网络限制使远程签名比当今许多人使用的私钥管理实践更安全。话虽如此,这里的星号是我为端到端消息安全实现了自己的密码系统。如果设计或实现中存在漏洞,密码系统就会崩溃,从而防止消息伪造。届时,恶意服务器或特权网络攻击者可能会迫使某人签署不需要的软件。但这可能是损害的程度:对签名密钥的离线攻击是不可能的,因为签名需要存在并且私钥永远不会通过网络传输。即使没有端到端加密,该系统也比将您的私钥作为容易被盗的CI机密(或类似机密)留在身边要安全得多。AppleKeychain支持从0.14版开始,我们现在可以早期支持使用存储在AppleKeychain中的代码签名证书进行签名!如果您在KeychainAccess或Xcode中创建了Apple代码签名证书,那么这可能就是您的代码签名证书所在的位置。我拖了很久,因为我没有意识到这会有多好:如果你使用macOS,就使用Apple的官方工具。但是随着rcodesign获得对远程代码签名的支持,以及其他一些可以使其成为所有平台上Apple工具的强大替代品的功能,我认为我们应该提供此功能,这样我们就不会阻止人们从私钥导出钥匙链。苹果的代码签名很复杂。Apple的工具和rcodesign之间很容易有细微的差别。rcodesign现在有print-signature-info和diff-signatures命令来转储和比较与代码签名相关的YAML元数据,从而更容易比较代码签名实现之间甚至多个签名操作之间的行为。本文翻译自:https://gregoryszorc.com/blog/2022/04/25/expanding-apple-ecosystem-access-with-open-source,-multi-platform-code-signing/如有转载请注明原文地址。