Fehlermeldung
Provided key is too short
Auch ausgegeben als
- DomainException: Provided key is too short
Wird sowohl von `JWT::encode` als auch von `JWT::decode` geworfen. php-jwt 6.x und älter akzeptierten kurze Schlüssel, deshalb tritt der Fehler typischerweise direkt nach dem Upgrade auf 7.x auf.
firebase/php-jwt 7.x (PHP) — DomainException from JWT::encode / JWT::decode
Was der Fehler bedeutet
Vor dem Signieren oder Verifizieren prüft php-jwt 7 die Schlüssellänge: Ein HMAC-Secret muss mindestens so viele Bits haben wie der Hash (32 Byte für HS256, 48 für HS384, 64 für HS512), ein RSA-Schlüssel mindestens 2048 Bit und ein EC-Schlüssel mindestens die Größe, die sein Algorithmus vorgibt. Ein kürzerer Schlüssel wird abgelehnt, weil sich damit geschützte Tokens fälschen lassen – kurze HMAC-Secrets lassen sich offline per Brute Force knacken, und 1024-Bit-RSA liegt unter den heutigen Mindestwerten.
Warum der Fehler auftritt
Ein kurzes, von Menschen ausgedachtes HMAC-Secret
häufigWerte wie `secret`, `change-me-please` oder ein App-Name liegen weit unter 32 Byte und lassen sich oft auch noch erraten.
Upgrade von php-jwt 6.x auf 7.x
häufigVersion 7 hat die Prüfung der Mindestschlüssellänge eingeführt. Code und Secrets, die jahrelang funktioniert haben, scheitern bei der ersten Anfrage nach `composer update`.
Ein 1024-Bit-RSA-Schlüssel
gelegentlichAlte, mit 1024 Bit erzeugte (oder aus Beispielen kopierte) Schlüssel werden für RS256/RS384/RS512 abgelehnt.
So behebst du den Fehler
- 1.
Neues zufälliges Secret generieren
Verwende `random_bytes` oder `openssl rand` und bewahre das Secret in einem Secrets-Manager auf. Eine Rotation macht bestehende Tokens ungültig; plane deshalb bei Bedarf eine kurze Überlappung ein.
bash # HS256 needs >= 32 bytes, HS512 >= 64; generate and store as base64 php -r 'echo base64_encode(random_bytes(64)), PHP_EOL;' - 2.
base64-kodiert speichern, die dekodierten Bytes verwenden
Prüfe die Länge einmal beim Start, damit ein schwaches Secret schon die Bereitstellung scheitern lässt statt erst die erste Anfrage.
php $secret = base64_decode(getenv('JWT_SECRET_B64'), true); if ($secret === false || strlen($secret) < 32) { throw new RuntimeException('JWT_SECRET_B64 must decode to at least 32 bytes'); } $token = JWT::encode($claims, $secret, 'HS256'); $decoded = JWT::decode($token, new Key($secret, 'HS256')); - 3.
Kleine RSA-Schlüssel ersetzen
Erzeuge einen RSA-Schlüssel mit 2048 Bit oder mehr – oder steige auf ES256 mit einem P-256-Schlüssel um – und veröffentliche den neuen öffentlichen Schlüssel, bevor du damit signierst.
bash openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out rs256-private.pem