Você sabia que um JWT pode ser assinado com JWS ou criptografado com JWE? E que o melhor algoritmo pra assinar não é HMAC que você aprendeu no tutorial do Medium ou com algum Microsoft MVP?

O dieal é o ES256 (ECDSA P-256 SHA-256)? Se não sabia, larga o café e lê com atenção pra não mandar bobagem na próxima daily.

Formulas on an old blackboard

Json Web Token (JWT)

O JWT é só um JSON compacto e URL safe, ideal pra trocar informações entre client e API sem quebrar a URL do browser. Pense nele como aquela classe abstrata que ninguém quer implementar, mas que você precisa pra manter seu código "elegante".

JWT pode ser implementado como JWS (Json Web Signature) ou JWE (Json Web Encryption).

O JWT carrega as famosas claims que nada mais é do que um chave/valor que informa quem é o usuário sem precisar bater no banco toda hora (amém!).

Quando você usa JWT, geralmente é pra mandar informações entre SPA e API, ou até mesmo entre APIs internas.

JWT faz parte da famila do JOSE (framework Javascript Object Signing & Encryption), que descreve as especificações pra assinar ou criptografar JWTs. Sim, JOSE é um "framework" pra garantir que você não faça merda com JWT.

AcrônimoNomeO que faz?
JWSJson Web Signature (RFC7515)Assinatura digital do JWT
JWEJson Web Encryption (RFC7516)Criptografia do JWT
JWKJson Web Key (RFC7517)Representação JSON de uma chave criptográfica
JWAJson Web Algorithm (RFC7518)Algoritmos válidos pra assinar/criptografar

JOSE garante a integridade dos dados enquanto trafegam na web, porque ninguém confia no seu HTTPS.

Json Web Signature (JWS)

Se você assinou seu JWT digitalmente, parabéns: você criou um JWS.

Essa assinatura digital é feita da junção do header e payload criptografados com a chave privada. Algo assim (simplificado pra você não chorar):

Encrypt(header + '.' + payload, secret);

Sim, eu sei que isso não é código real, não precisa enhcer meu saco.

Isso significa que o payload do JWT pode até ser legível, mas qualquer mudança mínima nele explode a assinatura. A API usa a chave pública pra validar se alguém mexeu no conteúdo, evitando que seu app tenha "features inesperadas".

Um JWS tem três partes:

  • Header (informações do algoritmo)
  • Payload (dados úteis)
  • Assinatura Digital

Exemplo prático de JWS

  • Header
{
  "alg": "ES256",
  "typ": "JWT"
}
  • Payload
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
  • Digital Signature
{
  "signature": "MEYCIQDx...Fy9A=="
}

Resultado final é algo assim (base64url, é claro):

header.payload.signature

JWS

Json Web Encryption (JWE)

Se só assinatura digital não é suficiente (porque você trabalha com paranoicos), então use JWE. Além do JWT assinado, ele também criptografa o conteúdo.

O JWE tem:

  • Header
  • Encrypted Key (chave criptografada)
  • Initialization Vector
  • Additional Authenticated Data (AAD)
  • Ciphertext (conteúdo criptografado)
  • Authentication Tag

A estrutura final é:

header.encrypted_key.iv.ciphertext.tag

JWE

Json Web Algorithms (JWA)

Nem todo algoritmo é digno do seu JWT. A RFC deixa claro: para assinar use ES256 ou PS256, senão você está brincando com a segurança da empresa.

JWS - Algoritmos disponíveis

AlgoritmoDescrição
HS256HMAC usando SHA-256
RS256RSASSA-PKCS1-v1_5 usando SHA-256
ES256ECDSA com P-256 usando SHA-256 (recomendado)
PS256RSASSA-PSS usando SHA-256
noneSem assinatura (sério? cuidado com isso!)

Sim, existe o "none", pra você brincar de segurança e torcer pra não virar meme na comunidade.

Json Web Key (JWK)

O JWK é o JSON que representa a chave criptográfica. Normalmente gerenciado por um servidor OAuth 2.0, ele permite validação pública sem expor dados sensíveis.

  • Exemplo de JWK Público (Google)
{
  "kty": "RSA",
  "e": "AQAB",
  "use": "sig",
  "kid": "1b94c",
  "n": "vrjO7..."
}
  • Exemplo de JWK Privado
{
  "kty": "RSA",
  "d": "PRIVATE_KEY_PART",
  "e": "AQAB",
  "use": "sig",
  "kid": "1b94c",
  "n": "vrjO7..."
}

Json Web Key Set (JWKS)

JWKS é apenas um conjunto de JWKs. Ele facilita atualizar algoritmos sem explodir tokens antigos—porque sim, a criptografia envelhece rápido, principalmente com aquele seu código vazando memória.

Trocar o JWK a cada 90 dias é recomendação, mas todo mundo ignora até ser hackeado.

  • Exemplo JWKS Público do Google
{
  "keys": [
    {
      "kty": "RSA",
      "e": "AQAB",
      "kid": "abc123",
      "n": "..."
    }
  ]
}

Referências úteis (sim, você precisa delas)

E agora, depois de tudo isso, ainda tá achando que JWT é só jogar um Base64 e torcer pra ninguém perceber?