Testovanie
Crypto::fake() neexistuje a nie je potrebné: fasáda nevolá databázu, frontu, udalosti, poštu ani HTTP. Okrem náhodnosti a loaderov kľúčov je každé volanie čistá funkcia svojich argumentov, takže ho v testoch spúšťajte naozaj — a pri náhodnom výstupe overujte tvar, nie hodnotu.
Loadery kľúčov čítajú vašu konfiguráciu alebo disk a fromStorageOrGenerate() pri prvom štarte zapisuje. Všetko ide cez Storage a config() Laravelu, takže Storage::fake('local') a config([...]) vo vašich testoch už pokryjú fromStorageOrGenerate() aj loadery *FromConfig.
Testovacie kľúče a OTP vektory
Menný priestor Testing dáva vašej suite pripravený kľúčový materiál a známe OTP vektory namiesto ručne vyrábaných. Je súčasťou src/, no neimportuje žiadny symbol PHPUnit ani Pest:
use RoundlyConsulting\Crypto\Testing\TestKeys;
use RoundlyConsulting\Crypto\Testing\TestOtp;
$secret = TestKeys::hmacSecret(); // a fixed, valid 64-byte secret (every HS tier)
$rsa = TestKeys::rsa(); // ephemeral 2048-bit private key
$ec = TestKeys::ec('P-384'); // ephemeral EC private key
if (TestKeys::supportsEd25519()) {
$okp = TestKeys::ed25519(); // guard on hosts without ext-sodium
}
$code = TestOtp::codeAt(time()); // a valid TOTP code for TestOtp::SECRETTestKeys::hmacSecret() je pevný platný 64-bajtový tajný kľúč — dosť dlhý pre každú úroveň HS vrátane HS512 — a TestOtp::SECRET pevný base32 tajný kľúč; továrne RSA, EC a Ed25519 pri každom volaní vytvoria nové dočasné kľúče. Nikdy ich nepoužívajte v produkcii.
Jednorazové reťazce certifikátov
TestCertificates vytvára skutočne prepojené reťazce — so zapísaním vlastného dočasného openssl.cnf s potrebnými sekciami — takže žiadna suite nemusí ručne vyrábať CSR a rozšírenia CA. Kľúče CA sú EC P-256; list môže byť EC alebo RSA:
use RoundlyConsulting\Crypto\Testing\TestCertificates;
$ca = TestCertificates::chain(); // leaf → intermediate → root, genuinely linked
$ca->leafKey; // the leaf's PRIVATE key — sign your test token with it
$ca->x5c(); // ready to drop into a JWS `x5c` header
$ca->pinnedFingerprints(); // the [intermediate, root] slice a pinning verifier compares
$ca->pemBundle();
$rogue = TestCertificates::rogueLeaf($ca); // same subject, a different CA — breaks isLinked()
$self = TestCertificates::selfSigned(['app.test']);ext-openssl vždy nastaví notBefore na čas podpisu, preto scenáre expirovaného či ešte neplatného certifikátu vytvoríte vyhodnotením v inom okamihu, nie antedatovaním certifikátu:
$leaf = $ca->leaf();
$leaf->isExpiredAt($leaf->notAfter()->addDay()); // expired
$leaf->isNotYetValidAt($leaf->notBefore()->subDay()); // not yet valid
CarbonImmutable::setTestNow($leaf->notAfter()->addYear());Listy s rozšíreniami
TestLeafOptions doplní list o surové rozšírenia, OID rozšíreného použitia kľúča, SAN typu directoryName, prázdny subjekt alebo OU — takže otestujete vlastné čítanie rozšírenia cez Certificate::extension() a DerDecoder:
use RoundlyConsulting\Crypto\Testing\TestCertificates;
use RoundlyConsulting\Crypto\Testing\TestLeafOptions;
$nonce = random_bytes(32);
$chain = TestCertificates::chain(length: 2, leafOptions: new TestLeafOptions(
rawExtensions: ['1.2.840.113635.100.8.2' => "\x30\x24\xA1\x22\x04\x20".$nonce],
subjectOrganizationalUnit: 'Authenticator Attestation',
));
$chain->leaf()->extension('1.2.840.113635.100.8.2')->der; // exactly the bytes aboveVoliteľné Pest expectations
Päť Pest expectations je v súbore, ktorý sa nenačítava automaticky. Pripojte ho cez require vo vlastnom tests/Pest.php — je chránený podmienkou function_exists('expect'), takže sa za behu aplikácie nikdy nenačíta:
// tests/Pest.php
require dirname(__DIR__).'/vendor/roundly-consulting/crypto-for-laravel/src/Testing/pest-expectations.php';
expect($token)->toBeValidJws($verifier, Algorithm::RS256);
expect($code)->toBeValidTotp($secret);
expect($ca->chain)->toBeLinked(); // the math, not trust
expect($ca->leaf())->toBeSignedBy($ca->chain->get(1)); // the intermediate signed the leaf
expect($ca->chain->get(1))->toBeSignedBy($ca->root());
expect($jwk)->toHaveThumbprint('NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs');Kompletný test
use RoundlyConsulting\Crypto\Jose\Jws;
use RoundlyConsulting\Crypto\Signature\Algorithm;
use RoundlyConsulting\Crypto\Signature\Es;
use RoundlyConsulting\Crypto\Signature\Key\EcKey;
use RoundlyConsulting\Crypto\Testing\TestKeys;
use RoundlyConsulting\Crypto\Testing\TestOtp;
it('issues a verifiable ES256 token', function () {
$key = TestKeys::ec(); // ephemeral P-256 private key
$token = (new Jws)->sign([], ['sub' => 'alice'], new Es($key));
expect($token)->toBeValidJws(new Es(EcKey::public($key->publicPem())), Algorithm::ES256);
});
it('accepts the current TOTP code', function () {
expect(TestOtp::codeAt(time()))->toBeValidTotp(TestOtp::SECRET);
});Pripnutie času
Totp a Claims::assertTemporal() čítajú aktuálny čas cez CarbonImmutable::now(), preto ho pripnite pomocníkom Laravelu:
use Illuminate\Support\Carbon;
Carbon::setTestNow('2026-07-10 12:00:00');
// … assert TOTP codes / token expiry deterministically …
Carbon::setTestNow(); // clearVlastná suite balíka
Balík svoje správanie pripína zafixovanými testovacími vektormi z RFC, korpusmi Project Wycheproof a fuzz testami na každom vstupe, ktorý môže ovplyvniť útočník. Z klonu repozitára ich spustíte takto:
composer test
CRYPTO_FUZZ_ITERATIONS=100000 composer test # a longer fuzz runPrejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.