Pular para o conteúdo
ecdsa.com
JJWT (Java)Java

Mensagem de erro

The specified key byte array is 96 bits which is not secure enough for any JWT HMAC-SHA algorithm.

Também aparece como

  • io.jsonwebtoken.security.WeakKeyException: The specified key byte array is 96 bits which is not secure enough for any JWT HMAC-SHA algorithm.
  • io.jsonwebtoken.security.SignatureException: Unable to compute HS512 signature. Cause: The signing key's size is 256 bits which is not secure enough for the HS512 algorithm.
  • io.jsonwebtoken.security.WeakKeyException: The signing key's size is 256 bits which is not secure enough for the HS512 algorithm.

A contagem de bits reflete sua chave. `Keys.hmacShaKeyFor` diz “…not secure enough for any JWT HMAC-SHA algorithm”. Assinar com um algoritmo explícito para o qual a chave é curta demais faz a mensagem citar o algoritmo: o JJWT 0.12+ encapsula o erro como “SignatureException: Unable to compute HS512 signature. Cause: The signing key's size is 256 bits…”, e o 0.11 o lança diretamente como `WeakKeyException`.

JJWT (Java) — io.jsonwebtoken.security.WeakKeyException from Keys.hmacShaKeyFor / signWith

O que significa

O JJWT se recusa a criar uma chave HMAC com menos bits que a saída do hash do algoritmo: no mínimo 256 bits (32 bytes) para HS256, 384 para HS384 e 512 para HS512. A RFC 7518 §3.2 torna isso obrigatório (MUST), porque um segredo compartilhado curto pode ser recuperado offline por força bruta a partir de qualquer token assinado com ele — e, a partir daí, qualquer pessoa consegue emitir tokens válidos. O número na mensagem é o tamanho dos bytes que você forneceu.

Por que acontece

Como corrigir

  1. 1.

    Gerar um segredo aleatório do tamanho certo

    Use um valor criptograficamente aleatório (64 bytes cobrem todas as variantes de HMAC) e guarde-o, codificado em base64, em um gerenciador de segredos.

    bash
    # 64 random bytes, base64-encoded: enough for HS256, HS384 and HS512
    openssl rand -base64 64 | tr -d '\n'
  2. 2.

    Decodificar o segredo armazenado para bytes

    Crie a chave a partir dos bytes decodificados, e não do texto em base64, para que todos os serviços derivem a mesma chave.

    java
    import io.jsonwebtoken.io.Decoders;
    import io.jsonwebtoken.security.Keys;
    
    javax.crypto.SecretKey key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(System.getenv("JWT_SECRET_B64")));
    String token = io.jsonwebtoken.Jwts.builder().subject("user-42").signWith(key).compact();

Erros relacionados

Ver toda a base de erros de assinatura