PHPackages                             k2gl/sshsig - 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. k2gl/sshsig

ActiveLibrary[Security](/categories/security)

k2gl/sshsig
===========

Faithful, zero-dependency PHP verifier for the OpenSSH SSHSIG signature format (ssh-keygen -Y verify): armor and SSH-wire parsing, signature verification, and allowed\_signers matching.

1.0.0(today)00MITPHPPHP &gt;=8.1CI passing

Since Jun 30Pushed todayCompare

[ Source](https://github.com/k2gl/sshsig)[ Packagist](https://packagist.org/packages/k2gl/sshsig)[ Docs](https://github.com/k2gl/sshsig)[ RSS](/packages/k2gl-sshsig/feed)WikiDiscussions main Synced today

READMEChangelog (2)Dependencies (4)Versions (4)Used By (0)

k2gl/sshsig
===========

[](#k2glsshsig)

[![CI](https://camo.githubusercontent.com/b8c48225f0d1d6151f0b9f7f8fd4d4b8a37903878639482706c95a8aead834fc/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6b32676c2f7373687369672f63692e796d6c3f6272616e63683d6d61696e266c6162656c3d4349266c6f676f3d676974687562)](https://github.com/k2gl/sshsig/actions)[![Latest Stable Version](https://camo.githubusercontent.com/b5609b84312dadbbc518b6b9624f35abeb960a88b83e4302844d3835d00a42a3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6b32676c2f737368736967)](https://packagist.org/packages/k2gl/sshsig)[![Total Downloads](https://camo.githubusercontent.com/a06b11702547d7d0490768b812bd395afa1f9d5a8dd67082a6c7a749fcea4643/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6b32676c2f737368736967)](https://packagist.org/packages/k2gl/sshsig)[![PHPStan](https://camo.githubusercontent.com/4f0c17b6f2d649d1bd4381b961b7402dc6acf3544cc143003c551ee06e37c36a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c253230392d326135656137)](https://phpstan.org/)[![License](https://camo.githubusercontent.com/8a5540b80ce4ec4be3111f0a55ad20dd3a90bc6a83792153101d4d6445f076c1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6b32676c2f737368736967)](https://packagist.org/packages/k2gl/sshsig)

Sign and verify files with SSH keys in PHP, in the OpenSSH SSHSIG format that `ssh-keygen -Y sign/verify` produces (the signatures Git uses for commit and tag signing). Verifying checks the signer against an `allowed_signers` file; signing emits bytes `ssh-keygen -Y verify`accepts. No dependencies.

Fail-closed by design: anything malformed, unsupported, cryptographically invalid, or unauthorized throws — nothing is ever silently treated as verified.

Install
-------

[](#install)

```
composer require k2gl/sshsig
```

Requires PHP 8.1+ with `ext-sodium` (Ed25519) and `ext-openssl` (RSA and ECDSA) — both are bundled with most PHP builds.

Usage
-----

[](#usage)

### Verify a signature against an allowed\_signers file

[](#verify-a-signature-against-an-allowed_signers-file)

This is the equivalent of `ssh-keygen -Y verify -f allowed_signers -I  -n `.

```
use K2gl\Sshsig\AllowedSigners;
use K2gl\Sshsig\Exception\SshsigException;
use K2gl\Sshsig\SshsigVerifier;

$verifier = new SshsigVerifier;

try {
    $result = $verifier->verify(
        message: file_get_contents('release.tar.gz'),
        armoredSignature: file_get_contents('release.tar.gz.sig'),
        allowedSigners: AllowedSigners::fromFile('allowed_signers'),
        identity: 'alice@example.com',
        namespace: 'file',
    );

    echo "Verified: {$result->publicKey->fingerprint()}\n";
} catch (SshsigException $e) {
    // not verified — malformed, unsupported, bad signature, or unauthorized signer
    echo "Rejected: {$e->getMessage()}\n";
}
```

### Check a signature without authorizing the signer

[](#check-a-signature-without-authorizing-the-signer)

The equivalent of `ssh-keygen -Y check-novalidate -n `: confirm the signature is structurally sound and cryptographically valid under its own embedded key, then inspect it.

```
$signature = $verifier->checkNoValidate($message, $armoredSignature, namespace: 'git');

echo $signature->signatureAlgorithm;          // e.g. "ssh-ed25519"
echo $signature->publicKey->fingerprint();    // "SHA256:…"
```

### Sign a message

[](#sign-a-message)

Produce an SSHSIG signature (the `ssh-keygen -Y sign` operation). Provide the signing key — Ed25519 (a 64-byte libsodium secret key) or an OpenSSL RSA/ECDSA private key:

```
use K2gl\Sshsig\Ed25519SigningKey;
use K2gl\Sshsig\OpensslSigningKey;
use K2gl\Sshsig\SshsigSigner;

// Ed25519
$keypair = sodium_crypto_sign_keypair();
$signer = new SshsigSigner(new Ed25519SigningKey(sodium_crypto_sign_secretkey($keypair)));

// …or RSA / ECDSA from an OpenSSL private key (PEM)
$signer = new SshsigSigner(OpensslSigningKey::fromPem(file_get_contents('id_rsa')));

$armored = $signer->sign($message, namespace: 'file');          // sha512 by default
file_put_contents('message.sig', $armored);

// the resulting signature verifies with `ssh-keygen -Y verify` and with this library
```

`$signer->publicKey()` returns the matching `SshPublicKey` (e.g. to build an `allowed_signers`line). The default hash is `sha512`; pass `hashAlgorithm: 'sha256'` to switch.

### Inspect or build allowed\_signers in memory

[](#inspect-or-build-allowed_signers-in-memory)

```
$allowed = AllowedSigners::fromString(
