A adoção de JWT como “solução milagrosa” de segurança pra API é um exagero bem comum. Você provavelmente já caiu na armadilha clássica de achar que basta jogar uma chave no appsettings.json e pronto, “tá tudo protegido”.

Amigo… não é bem assim não.

DO NOT ENTER.

Grandes players como Cisco e IBM já batem na mesma tecla faz tempo: uma parte enorme dos incidentes tem origem dentro da própria empresa. Então, se sua estratégia é “guardar segredo igual receita de bolo no bloco de notas”, talvez seja hora de repensar.

E só pra deixar claro: o problema não é existir chave simétrica. O problema é o uso amador dela.


O exemplo clássico que todo mundo usa (e depois finge surpresa)

Sabe aquele padrão que todo dev júnior (e infelizmente alguns sêniors também) adoram?

  • pega a chave do appsettings.json
  • usa direto na configuração
  • chama isso de “segurança”

Gist do exemplo:

Nesse exemplo lindo, você tá puxando a chave direto do appsettings.json. Poderia estar no banco, poderia estar hardcoded (espero que não), mas qualquer uma dessas opções continua sendo uma tragédia anunciada.


Veja como é simples atacar

Você vai no querido jwt.io, cola o JWT que você gerou todo feliz e inocente, e começa a testar a “chavezinha segura” até abrir.

Vídeo:


Quando utilizar uma chave simétrica?

Num monolito velho de guerra, até dá pra aceitar. Agora, se você já está brincando de “Netflix wannabe” com vários microsserviços independentes, você ganha duas opções bem ruins:

  • Centralizar geração/validação num serviço só, criando um gargalo delicioso e uma latência de fazer chorar.
  • Espalhar a chave por todo lado, tipo brinde de festa junina, aumentando o risco de alguém mal-intencionado fazer a festa com seus tokens.

O jeito “adulto” de lidar com isso é implementar um servidor OAuth 2.0 com OpenID Connect, com discovery, JWKS e chaves assimétricas. É mais chato? É. Mas segurança não é brincadeira de criança.

Se você estiver mesmo no monolito raiz, pelo menos gere uma chave decente e guarde direito. Nada de “gerar chave como no exemplo acima”, porque aí sim você arrumou um problema real.


Como gerar uma chave simétrica decente

Na hora de criar sua chave, lembra do básico que quase ninguém faz:

  • usar classes de criptografia para a chave
  • tamanho adequado
  • Usar JWK

Nunca use texto simples. O .NET já pensou nisso por você.

Gist do exemplo de geração:

Duas coisas importantes ali:

  • a chave tem 64 bytes (não é frescura, é recomendação)
  • usa System.Security.Cryptography.RandomNumberGenerator porque segurança não é “senha com aniversário do cachorro”

Por que raios 64 bytes?

Porque segurança tem padrão. E sim, tem tabela.

algAlgoritmoTamanho da chave
HS256SHA-25664 bytes
HS384SHA-384128 bytes
HS512SHA-512128 bytes

A Microsoft reforça esses valores nas docs oficiais.


Armazenando a chave com dignidade

“Ah, mas gerar uma chave aleatória toda vez que iniciar o app é impraticável!”

Sim. Por isso você armazena a chave como JWK, do jeito certo.

Gist do exemplo de armazenamento:

Boas práticas que aparecem ali:

  • auto-geração segura
  • armazenamento protegido

Componentizando com Jwks.Manager

Você não precisa reinventar a roda com arame e sofrimento. Dá pra usar o Jwks.Manager pra facilitar o gerenciamento de JWKs, inclusive com expiração/rotação.


Conclusão

JWT não é vilão. A forma como a galera usa é que costuma ser.

Então antes de “confiar no token” porque tem três pontos e uma assinatura, lembra: se sua chave está tratada como config qualquer, sua segurança é config qualquer.

Dúvidas, críticas ou ironias adicionais, manda nos comentários.


Download

Confira o código completo no GitHub:


Referências