如何签署 PHP 源代码

Posted

技术标签:

【中文标题】如何签署 PHP 源代码【英文标题】:how to sign PHP sourcecode 【发布时间】:2017-05-23 11:23:39 【问题描述】:

我想分发一些 php 源代码, 我需要提供一种方法来验证这些源代码是否未被更改。

所以基本上我想给他们签名(如果可能的话,使用 PHP)然后检查他们的签名(使用 PHP 是强制性的,它必须在 linux 和 windows 上都可以工作)。

我一直在挖掘,我发现的是:

签名: 您可以使用PharData 创建一个 zip 存档 您可以使用openssl 创建pub/priv。 您可以使用Phar::setSignatureAlgorithm 对 PharData 进行签名 您似乎必须将公钥放在存档旁边(source(阅读步骤 3)): 公钥必须与 Phar 文件同名,并添加 .pubkey,并且必须与 Phar 位于同一目录中。 验证: 没找到,估计PharData::extractTo就够了

如果有人可以验证这个过程(或指出更好的过程),那将是一个很大的帮助。

因为我试图给出我从现在找到的理论解决方案,但是在理论和实践之间,它们应该是一个差距。特别是考虑到我是这个概念的新手,并且我的项目在安全方面扎实是最重要的。 我提醒一下,几年前使用苹果的签名过程是一件很痛苦的事情,我对自己创建安全解决方案的能力没有信心。

【问题讨论】:

我从您链接的文章中得到的信息:如果您签署的 PHAR 没有签出或 pubkey 丢失,它就不会执行 - 所以您无事可做。除此之外:你的问题是什么?只是“如果有人有反馈”就一个想法太宽泛了。 @FranzGleichmann :我的问题是“”。我提出了看似理论上的解决方案,但我不是专家,这可能是一个糟糕的解决方案。因此,问题仍然是“如何”,可能的答案是“按照您的建议”。我以这种方式编辑我的问题。谢谢 “如果有人能验证这个过程(或指出更好的过程),那将是一个很大的帮助。” - 你试过了吗?应该需要一个小时左右,然后你就会知道它适用于你的情况。 FWIW - 是的,该过程是正确的,但有两个澄清:首先,运行时解释器验证密钥。你不必那样做。其次,我发现使用签名 PHAR 的大型 Web 应用程序存在性能问题。 请注意,anybody 可以创建密钥对并签署源代码。您需要信任公钥来验证签名。文章写的方式是可以保存公钥,以便验证后续更新来自同一发件人。对于要信任的初始包,您要么需要使用可以信任链的证书(PKI),要么需要使用单独的通道验证公钥(例如,通过电话验证公钥的哈希值,例如那个)。 @MaartenBodewes:你是对的。我进行了一些搜索以了解该过程将如何进行,但我没有找到任何东西。我想公钥必须提交给一个证书颁发机构,由他验证一些关键点,然后......我不知道,他们提供什么材料以及如何将它们整合到流程中,因为我从什么猜猜,公钥不会改变...... 【参考方案1】:

关于已签名的 phar 文件,我上次检查时,默认行为是:

如果签名有效,从phar检索文件(如果是php则执行) 如果签名无效,则抛出错误 如果没有签名,从phar检索文件(如果是php则执行)

因此,只需剥离签名即可轻松绕过签名保护(实际上,您只需将文件标记为未签名)。您可以显式设置 phar.require_hash 选项,以删除实例中的此后门。

验证这些源代码没有被更改

嗯嗯。这有点模糊。由谁修改?如上所述,您需要客户端选择加入基于 phar 签名的安全模型。

有很多第三方 PHP 编码器通过混淆代码来工作。几乎所有这些都提供了可笑的保护水平。一些例外是 IonCube 编码器和 Zend 的编码器。我对这些不太熟悉,无法说出它们有多强大以及它们是否符合您的要求。

有几个开源 PHP 编译器可以将 PHP 源代码转换为 .so 扩展名(尤其是 Facebook HipHop),但我认为这两个都没有得到维护。

如果您只想确保客户可以使用经过验证的内容(并且您不担心客户会修改文件),那么只需使用 PGP 或 x509 的标准文件签名。

如果您想阻止您的客户修改 PHP 代码,那么我知道(并且自己还没有测试过)的唯一选择是将您的代码分发为 HHVM 字节码 - 但这并不抵抗逆向工程, 没有内在的、安全的验证机制,实际上并不是一种保护代码的方法。

【讨论】:

谢谢,因为我只是想确保客户使用的文件来自我。我使用嵌入包含文件的存档中的 json 文件,它依赖 openssl_sign 对源代码进行签名。该文件包含签名和一些有效负载(即公钥) 首先让我们使用正确的术语。 OP 正在寻找不可否认的代码签名。他想证明内容的来源,并且内容在传输过程中没有改变,所以你关于混淆的答案完全是题外话。代码签名是使用与为其公钥颁发的证书相对应的私钥完成的。此类证书必须由客户信任的 CA 签署。客户在他们这边做的事情确实是他们的问题,你不应该相信他们。您签署代码以确保如果有人运行它的更改版本,您不承担任何责任。 否 - OP 要求代码是防篡改的 - 这与不可否认性不同,但有很多重叠。不可否认性是一种证明某些数据出处的机制——这与在出处违约时决定做什么是不同的。 ioncube 和 Zend 的编码器都声称可以解决出处问题,并提供一种机制来执行基于此的策略。 他说“我需要提供一种方法来验证此源代码没有被更改。”在这种情况下,内容来源是隐含的,因为如果不签署初始版本,您无法证明某些内容没有更改。这会引起很多混乱,因为证书上有不同的标志可以从技术上解决问题,但主要区别在于它们的法律解释。代码签名,数字签名。和不可否认性在幕后做同样的事情,但只有其中一个具有法律约束力。

以上是关于如何签署 PHP 源代码的主要内容,如果未能解决你的问题,请参考以下文章

Apple 登录“invalid_client”,使用 PHP 和 openSSL 签署 JWT 进行身份验证

你如何签署你的 Firefox 扩展?

如何使用适用于 macOS 的 Visual Studio 代码为外部 Mac 应用商店签署和公证电子应用程序构建?

在 PHP 服务器上签署 .mobileconfig

补丁后如何签署ipa?

签署 Apple MDM 配置文件