Mensagem de erro
Provided key is too short
Também aparece como
- DomainException: Provided key is too short
O erro é lançado tanto por `JWT::encode` quanto por `JWT::decode`. O php-jwt 6.x e anteriores aceitavam chaves curtas, por isso o erro costuma aparecer logo depois da atualização para a 7.x.
firebase/php-jwt 7.x (PHP) — DomainException from JWT::encode / JWT::decode
O que significa
O php-jwt 7 confere o tamanho da chave antes de assinar ou verificar: um segredo HMAC precisa ter pelo menos tantos bits quanto o hash (32 bytes para HS256, 48 para HS384, 64 para HS512), uma chave RSA, pelo menos 2048 bits, e uma chave EC, pelo menos o tamanho que o algoritmo dela implica. Uma chave mais curta é rejeitada porque os tokens protegidos por ela podem ser forjados — segredos HMAC curtos caem diante de força bruta offline, e RSA de 1024 bits está abaixo dos mínimos atuais.
Por que acontece
Um segredo HMAC curto, inventado por uma pessoa
comumValores como `secret`, `change-me-please` ou o nome de um aplicativo ficam muito abaixo de 32 bytes e, muitas vezes, também são fáceis de adivinhar.
Atualização do php-jwt da 6.x para a 7.x
comumA versão 7 passou a conferir se o tamanho da chave atinge o mínimo. Código e segredos que funcionaram por anos falham na primeira requisição depois de `composer update`.
Uma chave RSA de 1024 bits
ocasionalChaves antigas geradas com 1024 bits (ou copiadas de exemplos) são rejeitadas para RS256/RS384/RS512.
Como corrigir
- 1.
Gerar um novo segredo aleatório
Use `random_bytes` ou `openssl rand` e guarde o segredo em um gerenciador de segredos. Trocar o segredo invalida os tokens existentes; por isso, planeje um curto período de sobreposição, se necessário.
bash # HS256 needs >= 32 bytes, HS512 >= 64; generate and store as base64 php -r 'echo base64_encode(random_bytes(64)), PHP_EOL;' - 2.
Armazenar em base64, usar os bytes decodificados
Valide o tamanho uma vez na inicialização, para que um segredo fraco faça o deploy falhar, e não a primeira requisição.
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.
Substituir chaves RSA pequenas
Gere uma chave RSA de 2048 bits ou maior — ou mude para ES256 com uma chave P-256 — e publique a nova chave pública antes de começar a assinar com a nova chave.
bash openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out rs256-private.pem