Skip to content

Repository files navigation

Epicrypt

Security & Standards Packagist Downloads License: MIT Packagist Version Packagist PHP Version GitHub Code Size Documentation

Epicrypt is a capability-first PHP security toolkit.

It provides focused security building blocks for:

  • Certificate / PKI / key exchange
  • Crypto primitives
  • Token security (JWT, payload, opaque)
  • Password and secret protection
  • Integrity verification
  • Secure generation
  • Data protection workflows
  • Security utilities (signed URL, CSRF, reset/action tokens)

Installation

composer require infocyph/epicrypt

Requirements

  • PHP >=8.4
  • ext-sodium, ext-openssl, ext-json, ext-hash

Usage Examples

Encrypt and decrypt a string

<?php

declare(strict_types=1);

use Infocyph\Epicrypt\DataProtection\ProtectionOptions;
use Infocyph\Epicrypt\DataProtection\StringProtector;
use Infocyph\Epicrypt\Generate\KeyMaterial\KeyMaterialGenerator;

$key = (new KeyMaterialGenerator())->forAead();
$options = new ProtectionOptions('application-secret');
$protector = StringProtector::create();

$ciphertext = $protector->protect('secret-value', $key, $options);
$plaintext = $protector->unprotect($ciphertext, $key, $options);

Encrypt and decrypt a file

<?php

declare(strict_types=1);

use Infocyph\Epicrypt\DataProtection\FileProtector;
use Infocyph\Epicrypt\DataProtection\ProtectionOptions;
use Infocyph\Epicrypt\Generate\KeyMaterial\KeyMaterialGenerator;

$key = (new KeyMaterialGenerator())->forSecretStream();
$options = new ProtectionOptions('file-backup');
$files = new FileProtector();

$files->protect('/data/plain.txt', '/data/plain.txt.ep2', $key, $options);
$files->unprotect('/data/plain.txt.ep2', '/data/plain.out.txt', $key, $options);

Rotate keys with a key ring

<?php

declare(strict_types=1);

use Infocyph\Epicrypt\DataProtection\ProtectionOptions;
use Infocyph\Epicrypt\DataProtection\StringProtector;
use Infocyph\Epicrypt\Security\KeyPurpose;
use Infocyph\Epicrypt\Security\KeyRing;
use Infocyph\Epicrypt\Security\KeyRingEntry;
use Infocyph\Epicrypt\Security\KeyStatus;

$ring = new KeyRing([
    new KeyRingEntry('2026-01', $oldKey, KeyStatus::FALLBACK, KeyPurpose::DATA_PROTECTION, 'xchacha20-poly1305-ietf'),
    new KeyRingEntry('2026-05', $newKey, KeyStatus::ACTIVE, KeyPurpose::DATA_PROTECTION, 'xchacha20-poly1305-ietf'),
]);

$options = new ProtectionOptions('rotating-data');
$protector = StringProtector::create();
$ciphertext = $protector->protectWithKeyRing('rotating-data', $ring, $options);
$result = $protector->unprotectWithKeyRing($ciphertext, $ring, $options);

Hash, verify and rehash password

<?php

declare(strict_types=1);

use Infocyph\Epicrypt\Password\PasswordHasher;

$hasher = new PasswordHasher();
$hash = $hasher->hashPassword('MyStrongPassword!2026');

$isValid = $hasher->verifyPassword('MyStrongPassword!2026', $hash);
$rehash = $hasher->verifyAndRehash('MyStrongPassword!2026', $hash);

Issue and verify CSRF token

<?php

declare(strict_types=1);

use Infocyph\Epicrypt\Security\CsrfTokenManager;

$csrf = new CsrfTokenManager('csrf-secret');
$token = $csrf->issueToken('session-1');

$ok = $csrf->verifyToken('session-1', $token);

Generate and verify signed URL

<?php

declare(strict_types=1);

use Infocyph\Epicrypt\Security\SignedUrl;

$signed = new SignedUrl('url-secret');
$url = $signed->generate('https://example.com/download', ['file' => 'report.pdf'], time() + 300);

$ok = $signed->verify($url);

Issue and verify JWT (HS512)

<?php

declare(strict_types=1);

use Infocyph\Epicrypt\Token\Jwt\JwtClaims;
use Infocyph\Epicrypt\Token\Jwt\JwtPolicy;
use Infocyph\Epicrypt\Token\Jwt\SymmetricJwt;

$key = SymmetricJwt::generateBinaryKey();
$claims = JwtClaims::issue('issuer-service', 'user-1', ['api'], 600);
$token = SymmetricJwt::issuer($key, 'at+jwt')->issue($claims);
$verifier = SymmetricJwt::verifier($key, JwtPolicy::accessToken('issuer-service', 'api'));
$ok = $verifier->verify($token);

Generate certificate with SAN

<?php

declare(strict_types=1);

use Infocyph\Epicrypt\Certificate\CertificateOptions;
use Infocyph\Epicrypt\Certificate\Enum\OpenSslRsaBits;
use Infocyph\Epicrypt\Certificate\KeyPairGenerator;
use Infocyph\Epicrypt\Certificate\OpenSSL\CertificateBuilder;

$pair = KeyPairGenerator::openSsl(bits: OpenSslRsaBits::BITS_3072)->generate();
$dn = ['commonName' => 'service.example.test'];

$options = new CertificateOptions(
    sanDns: ['service.example.test', 'api.example.test'],
);

$certPem = (new CertificateBuilder())->selfSign($dn, $pair['private'], options: $options);

Security

Do not disclose suspected vulnerabilities in a public issue, discussion or pull request. Review the security policy, then use GitHub private vulnerability reporting to contact the maintainers confidentially.

Epicrypt is protected by PHPForge, an automated quality and security gate covering tests, static and taint analysis, dependency auditing, architecture checks, and release readiness. Automated controls reduce risk but do not replace responsible disclosure or manual review.


Made with ❤️ for the PHP community
MIT Licensed
DocumentationSecurityCode of ConductContributing
🗂️ BugFeatureDocumentationQuestionCI failure
🔀 GeneralBug fixFeatureRefactorPerformanceSecurity & reliabilityDocumentationMaintenance

About

Modern cryptography, token, password and data-protection toolkit for PHP.

Resources

Code of conduct

Contributing

Security policy

Stars

4 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages