Načítanie a generovanie kľúčov
Každý kľúč, ktorý signery prijímajú, zostavíte cez Crypto::keys() — rsa(), ec(), ed25519() a hmac() — načítaný, vygenerovaný alebo vytvorený pri prvom spustení:
use RoundlyConsulting\Crypto\Facades\Crypto;
$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); // raw 32-byte public key
$secret = Crypto::keys()->hmac()->fromConfig('services.webhook.secret');
// Load, or generate-and-persist on first boot:
$hmac = Crypto::keys()->hmac()->fromStorageOrGenerate('local', 'keys/hmac.key');
// A fresh secret, returned and never cached (shortcut for keys()->hmac()->generate(48)):
$fresh = Crypto::generateHmacSecret(48);Pre Ed25519 fasáda používa rovnaké slová public/private ako RSA a EC: public je surový 32-bajtový kľúč, private 64-bajtový tajný kľúč libsodium.
Triedy kľúčov
Každá trieda kľúča má základnú továreň bez konfigurácie, ktorá nepotrebuje kontajner, konfiguráciu ani disk. Každá validuje už pri vstupe, takže kľúč je buď silný a použiteľný, alebo sa odmietne s typovaným dôvodom:
use RoundlyConsulting\Crypto\Signature\Key\EcKey;
use RoundlyConsulting\Crypto\Signature\Key\HmacSecret;
use RoundlyConsulting\Crypto\Signature\Key\OkpKey;
use RoundlyConsulting\Crypto\Signature\Key\RsaKey;
$secret = HmacSecret::fromString($raw); // ≥ 32 bytes, never a PEM
$rsa = RsaKey::private($privatePem); // RSA 2048–8192 bits
$rsaPub = RsaKey::public($publicPem);
$ec = EcKey::private($pem); // curve auto-detected: P-256 / P-384 / P-521
$ecPub = EcKey::fromCoordinates($x, $y, 'P-256'); // raw COSE/JWK point
$rsaJwk = RsaKey::fromModulusExponent($n, $e); // raw COSE/JWK modulus + exponent
$okp = OkpKey::ed25519($rawPublic); // 32-byte Ed25519 public keyValidačné kontroly
- HmacSecret — odmietne prázdne hodnoty, čokoľvek s materiálom verejného kľúča (PEM aj za medzerami či UTF-8 BOM a surové DER bajty kľúča — blokuje zámenu RS256→HS256), tajné kľúče kratšie než 32 bajtov a kľúče z jediného opakovaného bajtu. Vyhadzuje WeakKeyException. HS384 a HS512 potrebujú 48 a 64 bajtov — to kontroluje signer Hs. Hodnotu začínajúcu na file:// nikdy neodovzdá OpenSSL, takže danú cestu nikdy neotvorí — posúdi ju ako obyčajný reťazec.
- RsaKey — musí ísť o RSA s 2048–8192 bitmi a nepárnym verejným exponentom aspoň 3. Príliš veľký surový modul sa odmietne ešte pred parsovaním.
- EcKey — iba P-256, P-384 alebo P-521; krivka sa zistí zo samotného kľúča.
- OkpKey — surový 32-bajtový verejný kľúč Ed25519 alebo 64-bajtový tajný kľúč libsodium; materiál nesprávnej dĺžky vyhodí KeyLoadException. fromSecretKey() zostaví pár znova zo seedu, takže tajný kľúč, ktorého verejná polovica patrí inému seedu, vyhodí KeyLoadException::mismatchedKeyPair().
Z disku alebo z vašej konfigurácie
Voliteľné loadery natívne pre Laravel čítajú materiál z ľubovoľného disku alebo z vášho konfiguračného kľúča a spúšťajú presne tie isté kontroly ako základná továreň. Chýbajúci súbor (či už disk vráti null, alebo je nastavený s 'throw' => true), neznámy názov disku, neúspešný zápis vo fromStorageOrGenerate() alebo chýbajúca, prázdna (aj len z medzier) či nereťazcová hodnota v konfigurácii vyhodí Signature\KeyLoadException — nikdy PHP warning ani výnimku súborového systému; pôvodná výnimka zostáva v getPrevious():
use RoundlyConsulting\Crypto\Signature\Key\HmacSecret;
use RoundlyConsulting\Crypto\Signature\Key\RsaKey;
use RoundlyConsulting\Crypto\Signature\Key\EcKey;
use RoundlyConsulting\Crypto\Signature\Key\OkpKey;
// From a filesystem disk (any configured disk name):
$secret = HmacSecret::fromStorage('local', 'keys/hmac.key');
$rsa = RsaKey::privateFromStorage('local', 'keys/rsa.pem');
$rsaPub = RsaKey::publicFromStorage('local', 'keys/rsa.pub');
$ec = EcKey::privateFromStorage('local', 'keys/ec.pem');
$okp = OkpKey::ed25519FromStorage('local', 'keys/ed25519.pub'); // 32 raw bytes
// From YOUR config key (explicit — the package reads no config on its own):
$secret = HmacSecret::fromConfig('services.webhook.secret');
$rsa = RsaKey::privateFromConfig('jwt.private_key');
$ecPub = EcKey::publicFromConfig('tokens.public_key');Továrne PEM — public() / private() pri RsaKey a EcKey, Certificate::fromPem() a Chain::fromPems() — prijímajú text PEM, nikdy cestu: reťazec file://…, ktorý by funkcie OpenSSL v PHP načítali z disku, sa odmietne ako nečitateľný. Súbory načítavajte cez fromStorage().
Loadery verejných kľúčov — RsaKey::public(), EcKey::public(), OkpKey::ed25519() a ich podoby cez Crypto::keys() — označujú svoj vstup #[\SensitiveParameter] rovnako ako tie súkromné: súkromné kľúče prichádzajú v tých istých formátoch, takže kľúč odovzdaný omylom zostane mimo stack trace výnimky, ktorá ho odmietne.
Generovanie nového materiálu
$secret = HmacSecret::generate(); // 32 random bytes (≥256 bits); pass a larger byte count if you like
$rsa = RsaKey::generate(2048); // or 3072 / 4096
$ec = EcKey::generate('P-256'); // or P-384 / P-521
$okp = OkpKey::generate(); // Ed25519, needs ext-sodiumHmacSecret::generate() prijíma 32 až 1024 bajtov — pre signer HS384 alebo HS512 zadajte 48 alebo 64. RsaKey::generate() a EcKey::generate() potrebujú funkčnú konfiguráciu OpenSSL (openssl.cnf); načítanie PEM, podpisovanie ani overovanie ju nepotrebujú. Na serveri s chýbajúcou alebo poškodenou konfiguráciou generate() vyhodí KeyLoadException namiesto PHP warningu.
Načítať, alebo pri prvom štarte vygenerovať a uložiť
fromStorageOrGenerate() načíta kľúč z cesty na disku, alebo — iba ak súbor chýba — vygeneruje nový, zapíše ho so súkromnou viditeľnosťou a vráti ho. Existujúci, no neplatný súbor sa nikdy neprepíše; stále vyhodí výnimku. Neúspešný zápis vyhodí KeyLoadException — vygenerovaný kľúč, ktorý sa neuložil, by pri ďalšom štarte nahradil iný. Pri asymetrických kľúčoch sa ukladá súkromný PEM (Ed25519 ukladá 64-bajtový tajný kľúč), verejnú polovicu si preto uložte sami:
use Illuminate\Support\Facades\Storage;
// Bootstraps a secret on first run, reuses it forever after:
$secret = HmacSecret::fromStorageOrGenerate('local', 'keys/hmac.key');
// Asymmetric: private PEM is written; persist the public half alongside it:
$key = RsaKey::fromStorageOrGenerate('local', 'keys/rsa.pem', bits: 3072);
Storage::disk('local')->put('keys/rsa.pub', $key->publicPem(), 'private');
$ec = EcKey::fromStorageOrGenerate('local', 'keys/ec.pem', curve: 'P-384');
$okp = OkpKey::fromStorageOrGenerate('local', 'keys/ed25519.key'); // 64-byte secret, ext-sodiumSúbežné prvé štarty dostanú jeden kľúč. Generovanie beží pod výhradným zámkom flock(), kontrola existencie sa vnútri neho zopakuje a vráti sa kľúč spätne načítaný z disku, takže proces, ktorý súboj prehral, prevezme kľúč víťaza namiesto toho, aby ho prepísal. Na lokálnom disku je zámkom prázdny súbor <key>.lock vedľa kľúča, spoločný pre všetky procesy a kontajnery, ktoré adresár pripájajú — nechajte ho na mieste. Na inom disku je to súbor zámku v systémovom dočasnom adresári, ktorý zoradí procesy len jedného servera, preto na zdieľanom objektovom úložisku kľúč pripravte raz, ako krok nasadenia. Adresár, v ktorom proces zámok vytvoriť nevie, vyhodí KeyLoadException::unlockable(). Ak kľúč už existuje, žiadny zámok sa neberie a nič sa nezapisuje, takže funguje aj adresár kľúčov len na čítanie.
Na lokálnom disku sa nový kľúč zapíše do dočasného súboru vedľa neho, prístupného len vlastníkovi (0600), dostane súkromnú viditeľnosť a jedným krokom sa premenuje na cieľovú cestu — nikdy teda nie je viditeľný napoly zapísaný ani čitateľný pre ostatných. Ak ktorýkoľvek krok zlyhá, na ceste kľúča nezostane nič a ďalší štart vygeneruje nový.
$bytes, $bits a $curve určujú len nový kľúč. Ak súbor existuje, platí uložený kľúč tak, ako je — požiadavka na P-384 uložený kľúč P-256 nezmení. Ich zmena v konfigurácii preto znamená zámernú rotáciu kľúča: starý verejný kľúč nechajte overovateľom dostupný, kým nevyprší každý token, ktorý podpísal.
Súkromná viditeľnosť závisí od drivera: na lokálnom drivere znamená práva len pre vlastníka, no na niektorých objektových úložiskách je to hrubšie ACL alebo nemá žiadny efekt. Tajný kľúčový materiál ukladajte iba na súkromný disk pod vašou kontrolou — nikdy na verejne servírovaný.
Export PEM
Ukladáte kľúče inde než na Laravel disk? RsaKey a EcKey exportujú obe polovice — privatePem() (PKCS#8) a publicPem() (SPKI). privatePem() na verejnom kľúči vyhodí KeyLoadException::notPrivate(), takže kľúč určený len na overovanie sa nikdy nezamení za podpisový materiál:
$key = RsaKey::generate(2048);
file_put_contents('/etc/app/private.pem', $key->privatePem()); // secret — chmod 0600
file_put_contents('/etc/app/public.pem', $key->publicPem());OkpKey exportuje verejnú polovicu cez publicPem() — ako PEM SubjectPublicKeyInfo podľa RFC 8410 (-----BEGIN PUBLIC KEY-----, OID 1.3.101.112), v rovnakom tvare, aký vracajú RsaKey::publicPem() a EcKey::publicPem(). Funguje aj na kľúči len s verejnou polovicou a nepotrebuje ext-sodium ani ext-openssl. Je určený pre verifiery, ktoré načítavajú verejné kľúče z PEM — OpenSSL, knižnicu JOSE či inú službu; samotný balík načíta verejný kľúč Ed25519 späť ako surových 32 bajtov:
use RoundlyConsulting\Crypto\Signature\Key\OkpKey;
$key = OkpKey::fromStorageOrGenerate('local', 'keys/ed25519.key'); // needs ext-sodium
$key->publicPem(); // -----BEGIN PUBLIC KEY----- (RFC 8410, OID 1.3.101.112) for OpenSSL, a JOSE library, another service
$key->publicKey; // the raw 32 bytes OkpKey::ed25519() reads backBajty zodpovedajú výstupu openssl pkey -pubout aj vzorovému kľúču z RFC 8410 — oboje pripínajú testy. OkpKey drží iba Ed25519, preto je OID vždy id-Ed25519.
Prehľad tovární
| Prístup cez fasádu | Metódy |
|---|---|
Crypto::keys()->rsa() | public · private · fromModulusExponent · generate · publicFromStorage · privateFromStorage · publicFromConfig · privateFromConfig · fromStorageOrGenerate |
Crypto::keys()->ec() | public · private · fromCoordinates · generate · publicFromStorage · privateFromStorage · publicFromConfig · privateFromConfig · fromStorageOrGenerate |
Crypto::keys()->ed25519() | public · private · generate · publicFromStorage · privateFromStorage · publicFromConfig · privateFromConfig · fromStorageOrGenerate |
Crypto::keys()->hmac() | fromString · generate · fromStorage · fromConfig · fromStorageOrGenerate |
| Kľúč | Statické továrne |
|---|---|
HmacSecret | fromString · generate · fromStorage · fromConfig · fromStorageOrGenerate |
RsaKey | public · private · fromModulusExponent · generate · publicFromStorage · privateFromStorage · publicFromConfig · privateFromConfig · fromStorageOrGenerate |
EcKey | public · private · fromCoordinates · generate · publicFromStorage · privateFromStorage · publicFromConfig · privateFromConfig · fromStorageOrGenerate |
OkpKey | ed25519 · fromSecretKey · generate · ed25519FromStorage · ed25519FromConfig · secretKeyFromStorage · secretKeyFromConfig · fromStorageOrGenerate |
Ak je k dispozícii ext-sodium, tajné kľúče HmacSecret a OkpKey sa pri zániku objektu podľa možností vynulujú v pamäti — ide o dodatočnú ochranu, nie o záruku. HmacSecret::$value a OkpKey::$secretKey sa dajú čítať, no sú private(set), takže overený kľúč sa nikdy nedá vymeniť za neoverený.
Prejavte 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.