NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky
Crypto for Laravel

HMAC, hašovanie a HKDF

Hash\Hmac podpisuje a overuje kľúčované MAC — základ kontroly podpisov webhookov. Tajné kľúče sa odovzdávajú pri každom volaní a sú označené #[\SensitiveParameter]; trieda nedrží žiadny vlastný kľúč:

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

// GitHub-style "sha256=…" header check:
$expected = 'sha256='.Crypto::hmac(HashAlgorithm::Sha256)->signHex($request->getContent(), $webhookSecret);
$ok = Crypto::constantTimeEquals($expected, $request->header('X-Hub-Signature-256', ''));

// Deterministic digest → an indexable lookup column:
$lookupKey = Crypto::digest()->hex($emailLowercased);

// A per-purpose subkey from one root secret (HKDF):
$fingerprintKey = Crypto::hkdf()->derive($rootKey, 32, 'app/fingerprint');

Alebo volajte priamo triedy, ktoré fasáda sprístupňuje:

use RoundlyConsulting\Crypto\Hash\Hmac;
use RoundlyConsulting\Crypto\Hash\HashAlgorithm;

$hmac = new Hmac(HashAlgorithm::Sha256);

// GitHub-style "sha256=…" header check:
$expected = 'sha256='.$hmac->signHex($request->getContent(), $webhookSecret);
$ok = hash_equals($expected, $request->header('X-Hub-Signature-256', ''));

// Or verify raw signatures directly (constant-time):
$ok = $hmac->verify($payload, $signature, $webhookSecret);
MetódaVracia
sign($message, $key)HMAC ako surové bajty.
signHex($message, $key)HMAC ako hex malými písmenami.
verify($message, $signature, $key)bool — overenie podpisu v surových bajtoch v konštantnom čase.

Deterministické digesty

Hash\Digest pre rovnaký vstup vždy vráti rovnaký výstup — práve to umožňuje indexované vyhľadávanie podľa zhody nad hašovanými dátami, napríklad slepý index nad e-mailom alebo tokenom:

use RoundlyConsulting\Crypto\Hash\Digest;

$digest = new Digest;                       // SHA-256

$lookupKey = $digest->hex($emailLowercased);          // deterministic → indexable column
$peppered  = $digest->withPepper($token, config('app.pepper')); // HMAC when a pepper is set
$raw       = $digest->raw($data);                     // raw bytes

withPepper() robí voľbu medzi obyčajným a kľúčovaným digestom explicitnou: obyčajný digest zvolí iba null. Akýkoľvek iný pepper — aj medzera či prázdny reťazec — sa použije doslovne ako HMAC kľúč, takže prázdna hodnota nikdy potichu nezníži kľúčovaný digest na obyčajný. Dáta odovzdané do raw(), hex() a withPepper() — tokeny, heslá, osobné údaje — sú tiež označené #[\SensitiveParameter].

HKDF — podkľúče pre každý účel

Hash\Hkdf implementuje odvodzovanie kľúčov extract-then-expand podľa RFC 5869: z jedného koreňového tajomstva nezávislé podkľúče pre každý účel, takže kľúč, ktorý pečatí hodnoty, nikdy zároveň nepočíta MAC odtlačku:

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

$fingerprintKey = Crypto::hkdf()->derive($rootKey, 32, 'app/fingerprint');       // no salt
$sealKey        = Crypto::hkdf(HashAlgorithm::Sha512)->derive($rootKey, 64, 'app/seal', 'app.hkdf/1');

Alebo volajte priamo triedu, ktorú fasáda sprístupňuje:

use RoundlyConsulting\Crypto\Hash\Hkdf;

$subkey = (new Hkdf)->derive($rootKey, 32, 'app/fingerprint');   // SHA-256 by default

derive(string $ikm, int $length, string $info = '', string $salt = '') vracia surové bajty:

  • $ikm, vstupný kľúčový materiál, je #[\SensitiveParameter] a nesmie byť prázdny.
  • $length je povinná: 1 až 255 × dĺžka hašu (8160 bajtov pre SHA-256). Funkcia hash_hkdf() v PHP číta 0 ako „jedna dĺžka hašu“; tu sa 0 odmietne, takže veľkosť odvodeného kľúča nikdy nie je implicitná.
  • $info pomenúva účel. Jeho polia oddeľte bajtom, ktorý žiadne pole nemôže obsahovať, napríklad NUL.
  • $salt je hodnota, ktorá nie je tajná (RFC 5869 §3.1); prázdna znamená „neuvedená“ — HashLen nulových bajtov.
  • Výstup je bajt po bajte zhodný s hash_hkdf(), čo pripínajú vektory z prílohy A RFC 5869 (SHA-256 aj SHA-1). SHA-1 zostáva dostupné len pre kompatibilitu (HashAlgorithm::isLegacy()).
  • Prázdny $ikm alebo $length mimo rozsahu vyhodí Hash\InvalidHkdfParameterException — programátorská chyba, nikdy nie vlastnosť dát.

Porovnanie v konštantnom čase

ConstantTime::equals() obaľuje hash_equals, aby každé porovnanie tajného kľúča, tagu či MAC prechádzalo jedným miestom a časovaním neprezradilo, aká časť hodnoty sa zhodovala. Oba vstupy sú #[\SensitiveParameter], rovnako ako pri hash_equals() v PHP: očakávaná hodnota je samotné tajomstvo, MAC, token či OTP, takže ani jeden sa nikdy nedostane do stack trace:

use RoundlyConsulting\Crypto\Hash\ConstantTime;

// $known is the trusted value, $user the attacker-influenced one:
$ok = ConstantTime::equals($knownExpected, $userSupplied);

Hašovacie algoritmy

PrípadHodnotaStav
HashAlgorithm::Sha1sha1Zastaraný — prelomený kolíziami, len pre kompatibilitu; isLegacy() vracia true.
HashAlgorithm::Sha256sha256Aktuálny (predvolený).
HashAlgorithm::Sha384sha384Aktuálny.
HashAlgorithm::Sha512sha512Aktuálny.

OTP je oddelené: RFC 6238 predpisuje SHA-1 a autentifikačné aplikácie ho používajú predvolene, preto Otp\OtpAlgorithm ponecháva SHA-1 ako plnohodnotnú voľbu.

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 kryptomien

Odoslaní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.