// kit 01
PQC Toolkit
Cripto post-cuántica lista para producción. Elige stack, elige primitiva, copia el código.
$ pqc_jwt.php
L3
1 <?php 2 declare(strict_types=1); 3 require __DIR__ . '/PqcSign.php'; // FFI wrapper for ML-DSA-65 via liboqs 4 5 final class HybridJwt 6 { 7 public function __construct( 8 private string $edPriv, 9 private string $edPub, 10 private string $pqPriv, 11 private string $pqPub, 12 private PqcSign $pq, 13 ) {} 14 15 public function issue(array $claims): string 16 { 17 $header = ['alg' => 'EdDSA+ML-DSA-65', 'typ' => 'JWT-HYBRID']; 18 $payload = $claims + ['iat' => time()]; 19 $hb = self::b64(json_encode($header, JSON_UNESCAPED_SLASHES)); 20 $pb = self::b64(json_encode($payload, JSON_UNESCAPED_SLASHES)); 21 $msg = "$hb.$pb"; 22 $sigEd = sodium_crypto_sign_detached($msg, $this->edPriv); 23 $sigPq = $this->pq->sign($msg, $this->pqPriv); 24 return "$msg." . self::b64($sigEd) . '.' . self::b64($sigPq); 25 } 26 27 public function verify(string $token): array | null 28 { 29 $parts = explode('.', $token); 30 if (count($parts) !== 4) return null; 31 [$hb, $pb, $sed, $spq] = $parts; 32 $msg = "$hb.$pb"; 33 if (!sodium_crypto_sign_verify_detached(self::ub64($sed), $msg, $this->edPub)) return null; 34 if (!$this->pq->verify($msg, self::ub64($spq), $this->pqPub)) return null; 35 return json_decode(self::ub64($pb), true); 36 } 37 38 private static function b64(string $b): string { return rtrim(strtr(base64_encode($b), '+/', '-_'), '='); } 39 private static function ub64(string $s): string { return base64_decode(strtr($s, '-_', '+/')); } 40 }
TAMAÑO CLAVE
1952 B pub
FIRMA / CT
3293 B sig
NIVEL NIST
L3
NOTAS
Verificación de JWT híbrido en PHP usando libsodium + FFI a liboqs.
- Coste de verificación vía FFI ~2 ms.
- Cachea la clave pública PQ parseada como FFI array tipado vía APCu.
- Verifica el token una vez en el gateway y pasa una claim al backend.