drupal/php-signify

符合Signify规范的签名验证

1.0.0 2020-03-02 14:34 UTC

This package is auto-updated.

Last update: 2024-08-29 05:18:32 UTC


README

PHP库,用于验证BSD Signify签名文件,以及PHP和shell实现的验证扩展CSIG签名文件。

PHP Composer

用例

Drupal的自动更新和核心验证工作依赖于对受信任的元数据和代码资产的操作。由于Drupal在全球范围内部署到各种环境中,我们的实现应支持数据的公共和私有镜像,以及支持广泛不同的PHP版本和网站托管配置的验证。拥有过时根证书、不安全的加密套件或过时TLS版本支持的托管不应损害对这些新Drupal特性的访问。

为什么选择Signify?

Signify是由OpenBSD创建的、用于使用现代密码学验证资产的事实标准。密码学基础完全可用在PHP的Sodium API中,并且通过sodium_compat可用于旧版PHP版本。因此,可以在当前Drupal版本支持的每个PHP版本上实现Signify。

Signify允许Drupal将信任锚定到初始安装时随盘提供的磁盘密钥。结合PHP版本中广泛支持的Signify密码学,我们可以在相当陈旧的基礎设施上建立信任。这与我们的目标相符,即构建支持安装长尾的更新功能。

扩展Signify

OpenBSD的构建和发布模型与Drupal不同。

首先,Drupal维护一个广泛的托管构建基础设施,涵盖了从核心到任意社区项目的所有内容。维护这些系统的可用性为保护秘密创造了挑战,我们希望保持信任根离线。

其次,我们的发布模型不是密钥轮换的强大基础。我们的主要发布间隔太长,无法轮换。我们的次要发布更频繁,但用户期望跨兼容性(以及必要的签名验证工作)可以跨越任意组合的次要版本和模块构建。网站所有者也可能在许多次要版本之间忽视他们的网站,这使得OpenBSD发布未来发布密钥的模型不足以维持连续性(例如,没有发送下一个10个密钥,并且如果其中一个相应的私钥泄露,几乎没有补救措施)。

从X.509中汲取一点灵感——重点是小的——我们将Signify扩展以支持链式签名。我们称此格式为CSIG。

使用CSIG进行链式签名

我们的目标是支持由HSM保护的离线根密钥。该HSM设置应定期为构建基础设施中的下一个公钥生成过期的签名。

我们可以使用Signify的构建块来实现这一点,但我们希望将组件打包到单个文件中,以便于分发和验证。

CSIG基础设施的初始设置

  1. 在HSM上生成密钥对。
  2. 导出公钥并打包成Signify的格式。
  3. 将此公钥与Drupal发布捆绑在一起。

在构建基础设施上的定期密钥轮换

  1. 在构建基础设施上生成密钥对。这可以自动完成,但不能使用,直到最终步骤将其提升为使用。
  2. 使用HSM签名并嵌入包含到期日期和构建基础设施公钥的消息。
  3. 将此签名消息上传到构建基础设施。这充当中间证书。

为构建生成一个CSIG

  1. 生成构建资产的有标签(BSD风格)sha512sum。
  2. 使用构建基础设施的密钥对生成的校验和列表进行签名和嵌入(使用OpenBSD术语)。
  3. 在前面添加中间证书。

使用CSIG验证资产

  1. 提取并验证中间证书与根公钥。
  2. 检查中间证书是否仍然有效(今天UTC时间不是在有效截止日期之后)。
  3. 从现在验证的中间证书中提取中间公钥。
  4. 提取已签名的校验和列表。
  5. 使用中间公钥验证签名的校验和列表。

CSIG的格式

加粗行是注释,不会出现在CSIG中。

  • 中间密钥及其过期时间
    • 不受信任的注释(行号1)
    • 由根密钥签名的Base64编码的签名(行号2)
    • 消息是一个过期的公钥,或xpub
      • UTC格式中的有效截止日期(YYYY-MM-DD格式,行号3)
      • Signify格式的构建基础设施公钥
        • “不受信任”的注释(行号4)
        • Base64编码的公钥(构建基础设施密钥)(行号5)
  • 使用行4-5上的密钥签名的消息或校验和列表
    • 不受信任的注释(行号6)
    • 由构建基础设施密钥签名的Base64编码的签名(行号7)
    • 消息或校验和列表
      • 消息或校验和列表条目(行8+)

如果只有一个校验和列表条目,则结果应该是九行,包括一个结尾的空行。每个额外的校验和列表条目增加一行。

一个可能的混淆点是行4以不受信任的注释开头,但实际上它是被根密钥签名的整体消息的一部分。这样做是为了允许在Signify格式中轻松使用构建基础设施公钥 - 它必须以字节不受信任的注释开头。

示例CSIG文件

untrusted comment: verify with root.pub
RWT/sFZ5HK1Dq7ML8TDNwKQGd40VZMEUXyC9bdI37YscjwO9+SZoyqmRSTWbJoQeGanRYpcBY4gxvKiWDjkwrVIqAksv0g08cwI=
2019-09-10
untrusted comment: build infrastructure key generated 2019-08-10
RWQ5TWYMFcc7gi3kSGCZrFm0rR4O0NnLvH603c4vMvHEvovmzzpgW8eC
untrusted comment: verify with build-infrastructure-20190810.pub
RWQ5TWYMFcc7gpE7lJZ2dbMK/x9iUPD08lfjGQtha9n4qIW/h7kQBjBcaYNNNKzQpJY3Xjgttm+TkxqlQNpz9sT+48mgC+xjCgY=
SHA512 (module.zip) = f53bef3e52bcbd7d822190a7458706ff5a4b10066a52e843ef10779b55f2b6ad16c928b42def63b2204af1e7c0baaf8d9ab1d172e2b78174626f42da90a15904

示例CLI创建CSIG文件

为了方便,此示例使用-n选项禁用密码。

$ signify -G -n -p root.pub -s root.sec
$ signify -G -n -p intermediate.pub -s intermediate.sec
$ date --utc --iso-8601 --date="+30 days" > expiration
$ cat expiration intermediate.pub | signify -S -e -s root.sec -m - -x intermediate.xpub.sig  # xpub = expiring public key
$ sha512sum --tag module.zip > module-checksum-list
$ signify -S -e -s intermediate.sec -m module-checksum-list -x module.sig
$ cat intermediate.xpub.sig module.sig > module.csig

示例CLI验证CSIG文件

必需的文件:root.pub module.zip module.csig

$ head --lines=5 module.csig > intermediate.xpub.sig
$ signify -V -e -p root.pub -m intermediate.xpub  # Verifies/extracts intermediate.xpub.sig, creates intermediate.xpub
$ head --lines=1 intermediate.xpub  # Displays valid-through date in UTC. Should be on or after the current date in UTC.
$ tail --lines=2 intermediate.xpub > intermediate.pub
$ tail --lines=+6 module.csig | signify -C -p intermediate.pub -x -

运行测试

sudo dnf install composer
git clone https://github.com/drupalassociation/php-signify
cd php-signify
composer install
vendor/bin/phpunit