NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Crypto for Laravel

The Crypto facade

Crypto fronts RoundlyConsulting\Crypto\CryptoManager, so typing Crypto:: shows every entry point — keys, signers, JOSE, JWK, X.509, ASN.1, hashing, authenticated encryption, COSE, OTP, CSPRNG and codecs. It is the recommended way in, and every section of these docs leads with it. Every factory still takes keys and knobs as explicit arguments; the manager reads no config and holds no secret:

use RoundlyConsulting\Crypto\Facades\Crypto;
use RoundlyConsulting\Crypto\Hash\HashAlgorithm;
use RoundlyConsulting\Crypto\Signature\Algorithm;

// Keys: every key family the signers take, loaded, generated or bootstrapped
$rsa    = Crypto::keys()->rsa()->privateFromStorage('local', 'keys/rsa.pem');
$rsaPub = Crypto::keys()->rsa()->publicFromConfig('jwt.public_key');
$ec     = Crypto::keys()->ec()->generate('P-384');
$ed     = Crypto::keys()->ed25519()->public($raw32Bytes);
$secret = Crypto::keys()->hmac()->fromConfig('services.webhook.secret');

// Signers and JOSE
$token  = Crypto::jws()->sign(['kid' => 'k1'], ['sub' => 'alice'], Crypto::rs($rsa));
$claims = Crypto::jws()->verify($token, Crypto::rs($rsaPub), Algorithm::RS256);
$sig    = Crypto::es($ec)->sign($message);               // raw r‖s, as JOSE wants it
$der    = Crypto::ecDer()->fromRaw($sig, 48);             // DER, as OpenSSL wants it
Crypto::verifier()->verify($publicKey, $message, $sig);   // the key picks the algorithm

// Hashing, encryption, OTP, JWK, X.509, COSE
Crypto::hmac(HashAlgorithm::Sha256)->verify($payload, $signature, $webhookKey);
$sealed = Crypto::aes256Gcm()->seal($dataKey, $plaintext, associatedData: 'invoices:42');
Crypto::totp(digits: 8)->verify($otpSecret, $code);
Crypto::jwk($ec)->thumbprint();
Crypto::x509()->fromPem($pem)->fingerprint();
Crypto::x509()->chain()->fromX5c($x5c)->isLinked();      // the math — the trust call stays yours
Crypto::coseKey($coseBytes);                             // COSE_Key bytes -> a public key

// Randomness and codecs return the value directly
$code   = Crypto::random()->numeric(6);
$apiKey = Crypto::random()->token(40);
$b64u   = Crypto::base64UrlEncode($bytes);

Codec and CSPRNG methods return the computed value; everything else returns a short-lived instance — a signer, a decoder, a key or a value object. Jwk, Certificate and Chain are value objects, fronted for discoverability and never registered as singletons.

Sub-accessors

Four methods return a small, stateless group of related factories. Each group method keeps its factory’s exact parameter names, types, defaults and exceptions — an architecture test pins that parity in both directions:

AccessorReturnsMethods
keys()Signature\Key\Keysrsa() · ec() · ed25519() · hmac() — one group per key family; see Loading & generating keys.
random()Random\Csprngbytes() · token() · numeric() · alphanumeric() · fromAlphabet() · secret() — CSPRNG values, returned directly.
x509()X509\CertificatesfromPem() · fromDer() · fromBase64() · chain() — certificates from PEM, DER or an x5c entry.
x509()->chain()X509\ChainsfromX5c() · fromPems() · fromPemBundle() · fromCertificates() — chains from x5c, PEM lists, bundles or parsed certificates.
ecDer()Signature\Ec\DerCodecfromRaw() · toRaw() · isValid() — ECDSA raw r‖s ↔ DER.

The flat shortcuts — certificate(), chainFromX5c(), chainFromPemBundle(), generateHmacSecret() and randomBytes() / randomToken() / randomSecret() — run through those same sub-accessors, so both spellings are the same code.

Every method, by area

AreaMethods
JOSE / JWKjws() · jwk($key) · jwkFromArray($members) · jwkFromJson($json)
Keyskeys()->rsa() / ->ec() / ->ed25519(): public() · private() · generate() · publicFromStorage() · privateFromStorage() · publicFromConfig() · privateFromConfig() · fromStorageOrGenerate(); rsa()->fromModulusExponent() · ec()->fromCoordinates()
HMAC secretskeys()->hmac(): fromString() · generate() · fromStorage() · fromConfig() · fromStorageOrGenerate(); shortcut generateHmacSecret($bytes = 32)
Signershs($secret, $algorithm) · rs($key, $algorithm) · es($key) · eddsa($key) · verifier()
ECDSA encodingecDer(): fromRaw($rawRS, $coordBytes) · toRaw($der, $coordBytes) · isValid($der)
X.509x509(): fromPem() · fromDer() · fromBase64() · chain() → fromX5c() · fromPems() · fromPemBundle() · fromCertificates(); shortcuts certificate($pem) · chainFromX5c($x5c) · chainFromPemBundle($bundle)
ASN.1 / DERderDecoder()
Hashinghmac($algorithm) · digest($algorithm) · constantTimeEquals($known, $user)
Authenticated encryptionaes256Gcm(): seal() · open() · encrypt() · decrypt()
COSE / WebAuthncbor() · coseKey($coseBytes) · authenticatorData($bytes)
OTPtotp($algorithm, $digits, $period) · hotp($algorithm, $digits) · provisioningUri($secret, $label, $issuer, …)
CSPRNGrandom(): bytes() · token() · numeric() · alphanumeric() · fromAlphabet() · secret(); shortcuts randomBytes() · randomToken() · randomSecret()
Codecsbase64UrlEncode / base64UrlDecode · base64Encode / base64Decode · base32Encode / base32Decode · hexEncode / hexDecode

Want the same API without static calls? See DI and direct classes.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.