Mensaje de error
Provided key is too short
También se muestra como
- DomainException: Provided key is too short
Lo lanzan tanto `JWT::encode` como `JWT::decode`. php-jwt 6.x y anteriores aceptaban claves cortas, así que el error suele aparecer justo después de actualizar a 7.x.
firebase/php-jwt 7.x (PHP) — DomainException from JWT::encode / JWT::decode
Qué significa
php-jwt 7 comprueba los tamaños de clave antes de firmar o verificar: un secreto HMAC debe tener al menos tantos bits como el hash (32 bytes para HS256, 48 para HS384, 64 para HS512), una clave RSA al menos 2048 bits y una clave EC al menos el tamaño que implica su algoritmo. Una clave más corta se rechaza porque los tokens que protege se pueden falsificar: los secretos HMAC cortos caen ante la fuerza bruta sin conexión, y RSA de 1024 bits está por debajo de los mínimos actuales.
Por qué ocurre
Un secreto HMAC corto, inventado por una persona
frecuenteValores como `secret`, `change-me-please` o el nombre de una aplicación quedan muy por debajo de 32 bytes y, además, suelen ser fáciles de adivinar.
Actualización de php-jwt de 6.x a 7.x
frecuenteLa versión 7 añadió la comprobación de un tamaño de clave mínimo. El código y los secretos que funcionaron durante años fallan en la primera solicitud después de `composer update`.
Una clave RSA de 1024 bits
ocasionalLas claves antiguas generadas con 1024 bits (o copiadas de ejemplos) se rechazan para RS256/RS384/RS512.
Cómo solucionarlo
- 1.
Generar un secreto aleatorio nuevo
Usa `random_bytes` u `openssl rand` y guarda el secreto en un almacén de secretos. Rotarlo invalida los tokens existentes, así que, si hace falta, planifica un breve periodo de solapamiento.
bash # HS256 needs >= 32 bytes, HS512 >= 64; generate and store as base64 php -r 'echo base64_encode(random_bytes(64)), PHP_EOL;' - 2.
Guardarlo codificado en base64 y usar los bytes decodificados
Valida la longitud una vez al arrancar, para que un secreto débil haga fallar el despliegue y no la primera solicitud.
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.
Sustituir las claves RSA pequeñas
Genera una clave RSA de 2048 bits o más —o pásate a ES256 con una clave P-256— y publica la nueva clave pública antes de firmar con ella.
bash openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out rs256-private.pem