puff/crypt

Authenticated encryption component for Puff

Maintainers

Package info

github.com/php-puff/crypt

pkg:composer/puff/crypt

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-08-19 16:24 UTC

This package is auto-updated.

Last update: 2026-08-19 16:28:32 UTC


README

Authenticated string encryption for Puff, powered by Sodium's XChaCha20-Poly1305 implementation.

Requirements

  • PHP 8.2 or later
  • The OpenSSL extension
  • The Sodium extension
  • puff/config and puff/di

Installation

composer require puff/crypt

Puff discovers Puff\Crypt\ServiceProvider automatically. Configure a non-empty application key at the root of the Puff configuration:

return [
    'key' => env('APP_KEY'),
];

Use a high-entropy secret and keep it stable between deployments. Changing the key makes existing ciphertext impossible to decrypt. The configured value is domain-separated and converted to the 32-byte Sodium key required by the default driver.

The provider refuses to configure the service when the Config component is unavailable or key is missing or empty. Puff Crypt never falls back to a shared default key.

Encrypting and Decrypting

Inject Puff\Crypt\Crypt:

use Puff\Crypt\Crypt;

final readonly class TokenStore
{
    public function __construct(private Crypt $crypt)
    {
    }

    public function store(string $token): string
    {
        return $this->crypt->encrypt($token);
    }

    public function restore(string $ciphertext): string
    {
        return $this->crypt->decrypt($ciphertext);
    }
}

The global facade is also available:

$ciphertext = Crypt::encrypt('secret');
$plaintext = Crypt::decrypt($ciphertext);

Each call uses a new random nonce, so encrypting the same plaintext twice produces different ciphertext. Empty strings and arbitrary binary strings are supported.

The result is a versioned, URL-safe text envelope:

puff:v1:sodium:<base64url-payload>

The version and driver name are authenticated with the ciphertext. Do not parse or modify the envelope in application code.

AES-256-GCM

Sodium remains the default driver. An authenticated AES-256-GCM driver backed by OpenSSL is registered as aes-256-gcm:

$ciphertext = $crypt->encrypt('secret', 'aes-256-gcm');
$plaintext = $crypt->decrypt($ciphertext);

Its envelope identifies the selected algorithm, so decryption routes automatically:

puff:v1:aes-256-gcm:<base64url-payload>

AES-GCM uses a fresh 96-bit nonce and a 128-bit authentication tag for every encryption operation. Prefer the default Sodium driver unless interoperability or platform requirements specifically call for AES-GCM.

Custom Drivers

A custom algorithm implements CryptContract:

use Puff\Crypt\CryptContract;

final class CustomDriver implements CryptContract
{
    public function encrypt(string $plaintext, string $associatedData = ''): string
    {
        // Return the binary encrypted payload.
    }

    public function decrypt(string $ciphertext, string $associatedData = ''): string
    {
        // Authenticate and return the plaintext.
    }
}

Register it under a lowercase name and select it while encrypting:

$crypt->extend('custom', new CustomDriver());

$ciphertext = $crypt->encrypt('secret', 'custom');
$plaintext = $crypt->decrypt($ciphertext);

The envelope records the driver name, so decrypt() selects the correct registered driver automatically. Driver names must begin with a lowercase letter and may contain lowercase letters, digits, underscores, and hyphens.

To replace the default implementation application-wide, bind Puff\Crypt\CryptContract before the Crypt service is resolved.

Error Handling

Invalid configuration, malformed envelopes, unknown drivers, modified ciphertext, and authentication failures throw Puff\Crypt\CryptException:

use Puff\Crypt\CryptException;

try {
    $plaintext = $crypt->decrypt($ciphertext);
} catch (CryptException $exception) {
    // Treat the value as invalid. Do not expose cryptographic details.
}

Puff Crypt performs reversible authenticated encryption. It is not a password hashing API. Store passwords with PHP's password_hash() and verify them with password_verify().

License

Puff Crypt is open-source software licensed under the MIT license.