PHPackages                             drupal/php-signify - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Security](/categories/security)
4. /
5. drupal/php-signify

AbandonedArchivedLibrary[Security](/categories/security)

drupal/php-signify
==================

Signify-compliant signature verification

1.0.0(6y ago)114.9k↓33.3%4[2 issues](https://github.com/drupal/php-signify/issues)MITPHPPHP &gt;=5.3.0

Since Oct 1Pushed 6y ago8 watchersCompare

[ Source](https://github.com/drupal/php-signify)[ Packagist](https://packagist.org/packages/drupal/php-signify)[ RSS](/packages/drupal-php-signify/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (3)Versions (4)Used By (0)

PHP Signify
===========

[](#php-signify)

PHP library for verification of BSD Signify signature files, plus PHP and shell implementations of verifying extended CSIG signature files.

[![PHP Composer](https://github.com/drupal/php-signify/workflows/PHP%20Composer/badge.svg)](https://github.com/drupal/php-signify/workflows/PHP%20Composer/badge.svg)

Use Case
--------

[](#use-case)

Drupal's auto-update and core validation work depends on access to trusted metadata and code assets. Because Drupal is deployed globally to diverse environments, our implementation should support public and private mirroring of data as well as validation by widely varying PHP releases and web host configurations. Hosts with outdated root certificates, insecure ciphers, or outdated TLS version support should not undermine access to these new Drupal features.

Why Signify?
------------

[](#why-signify)

Signify is a defacto standard created by OpenBSD to validate assets using modern cryptography. The cryptographic foundations are entirely available in PHP's Sodium APIs and are available for legacy PHP versions through sodium\_compat. Therefore, it is possible to implement Signify on every PHP version currently supported by current Drupal releases.

Signify allows Drupal to anchor trust to on-disk keys shipped with the initial installation. Combined with the broad supportability of Signify's cryptography in PHP releases, we can establish trust on quite outdated infrastructure. This fits with our goal of building update features that support the long tail of installations.

Extending Signify
-----------------

[](#extending-signify)

OpenBSD's build and release model differs from Drupal's.

First, Drupal maintains an extensive hosted build infrastructure that covers everything from core to arbitrary community projects. Maintaining the availability of these systems creates challenges for protecting the secrets, and we desire keeping the root of trust offline.

Second, our release model isn't a compelling foundation for key rotation. Our major releases happen at too long of an interval for rotation. Our minor releases are more frequent, but users expect cross-compatibility (and requisite signature validation to work) across arbitrary mixes of minor releases and module builds. Site owners may also neglect their site across quite a few minor releases, making OpenBSD's model of shipping future release keys insufficient for maintaining continuity (without, say, shipping the next 10 keys and having little recourse if one of the corresponding private keys leaks).

Taking a little inspiration from X.509 -- with an emphasis on little -- we've extended Signify to support chained signatures. We call this format CSIG.

Chaining with CSIG
------------------

[](#chaining-with-csig)

Our goal with CSIG is to support an offline root protected by an HSM. That HSM setup should periodically produce expiring signatures against the next public key for use within the build infrastructure.

We can accomplish this using the building blocks of Signify, but we'd like to pack the pieces into a single file for ease of distribution and validation.

Initial setup of CSIG infrastructure:

1. Generate a keypair on the HSM.
2. Export the public key and package in Signify's format.
3. Bundle this public key with Drupal releases.

Periodic key rotation on the build infrastructure:

1. Generate a keypair on the build infrastructure. This can happen automatically but not be used until promoted into use by the final step.
2. Use the HSM to sign and embed a message containing an expiration date and the build infrastructure's public key.
3. Upload that signed message to the build infrastructure. This functions as an intermediate certificate.

Generating a CSIG for a build:

1. Generate a tagged (BSD-style) sha512sum of the built asset.
2. Sign and embed the generated checksum list (to use the OpenBSD term) using the build infrastructure's secret key.
3. Prepend the intermediate certificate.

Validating an asset using a CSIG:

1. Extract and validate the intermediate certificate against the root public key.
2. Check that the intermediate certificate remains valid (today in UTC is not after the valid-through date).
3. Extract the intermediate public key from the now-validated intermediate certificate.
4. Extract the signed checksum list.
5. Validate the signed checksum list against the intermediate public key.

### Format of a CSIG

[](#format-of-a-csig)

Bold lines are annotations that do not occur in the CSIG.

- **Intermediate key and its expiration**
    - Untrusted Comment (line #1)
    - Base64-Encoded Signature by Root Secret Key (line #2)
    - **Message is an expiring public key, or xpub**
        - Valid Through Date in UTC in YYYY-MM-DD Format (line #3)
        - **Build Infrastructure Public Key in Signify Format**
            - "Untrusted" Comment (line #4)
            - Base64-Encoded Public Key (Build Infrastructure Key) (line #5)
- **Message or Checksum List signed with key on lines 4-5**
    - Untrusted Comment (line #6)
    - Base64-Encoded Signature by Build Infrastructure Key (line #7)
    - **Message or Checksum List**
        - Message or Checksum List Entries (lines 8+)

If there is only one checksum list entry, the result should be nine lines, including a blank line at the end. Each additional checksum list entry adds one line.

A possible point of confusion is that line 4 begins with `untrusted comment`, but in fact it is part of the overall message signed by the Root Secret Key. This is done to allow easy usage of the Build Infrastructure Public Key in Signify format - it must necessarily begin with the bytes `untrusted comment`.

#### Example CSIG File

[](#example-csig-file)

```
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

```

#### Example CLI Creation of a CSIG File

[](#example-cli-creation-of-a-csig-file)

For convenience, this example uses the `-n` option to disable passphrases.

```
$ 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

```

#### Example CLI Validation of CSIG File

[](#example-cli-validation-of-csig-file)

Requisite files: `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 -

```

Running Tests
-------------

[](#running-tests)

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

```

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance16

Infrequent updates — may be unmaintained

Popularity30

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~149 days

Total

2

Last Release

2269d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/27288432?v=4)[Drupal Infrastructure](/maintainers/Drupal-Infrastructure)[@Drupal-Infrastructure](https://github.com/Drupal-Infrastructure)

---

Top Contributors

[![davidstrauss](https://avatars.githubusercontent.com/u/113350?v=4)](https://github.com/davidstrauss "davidstrauss (23 commits)")[![mbaynton](https://avatars.githubusercontent.com/u/3026002?v=4)](https://github.com/mbaynton "mbaynton (9 commits)")[![heddn](https://avatars.githubusercontent.com/u/1581734?v=4)](https://github.com/heddn "heddn (8 commits)")[![pwolanin](https://avatars.githubusercontent.com/u/107691?v=4)](https://github.com/pwolanin "pwolanin (8 commits)")[![drumm](https://avatars.githubusercontent.com/u/39292?v=4)](https://github.com/drumm "drumm (1 commits)")[![Drupal-Infrastructure](https://avatars.githubusercontent.com/u/27288432?v=4)](https://github.com/Drupal-Infrastructure "Drupal-Infrastructure (1 commits)")

---

Tags

securitycryptographysignify

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/drupal-php-signify/health.svg)

```
[![Health](https://phpackages.com/badges/drupal-php-signify/health.svg)](https://phpackages.com/packages/drupal-php-signify)
```

###  Alternatives

[phpseclib/phpseclib

PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.

5.6k434.8M1.3k](/packages/phpseclib-phpseclib)[defuse/php-encryption

Secure PHP Encryption Library

3.9k162.4M214](/packages/defuse-php-encryption)[paragonie/ciphersweet

Searchable field-level encryption library for relational databases

4641.2M21](/packages/paragonie-ciphersweet)[rych/phpass

PHP Password Library: Easy, secure password management for PHP

248801.7k4](/packages/rych-phpass)[xxtea/xxtea

XXTEA is a fast and secure encryption algorithm. This is a XXTEA library for PHP.

11341.7k](/packages/xxtea-xxtea)[ph-7/passcode-password-generator

A simple way to generate random cryptographically secure passcodes and passwords

1223.4k2](/packages/ph-7-passcode-password-generator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
