Na documentação oficial do IdentityServer4, na seção Deployment há uma menção sobre Key Material e sua importancia no ambiente de produção. Mas você sabe o que é Key Material?
Em criptografia Key Material são os dados privados que compõem uma chave criptográfica. Esses dados permitem transformar um texto plano em texto cifrado. Ou seja, é a parte da chave que permite criptografar a mensagem.
Nem todas informações para criptografar uma mensagem são privados. Na criptografia assimétrica, parte dessas informações podem ser públicas. Assim o conteúdo da mensagem pode ser lido utilizando a chave pública. Porém para gerar o texto cifrado é necessário a chave privada.
Criptografia simétrica
Em um algoritmo simétrico uma única chave é utilizada. Tanto para criptografar os dados quanto na descriptografia. Portanto as duas partes envolvidas numa comunicação precisam ter a mesma chave. Seja para leitura, ou para escrever uma nova.
Esse formato exige que ambos sistemas cuidem corretamente da chave de criptografia. A chave de criptografia aumenta o Surface of Attack (Área de ataque) da sua aplicação, aumentando as chances de um ataque.
Chave Assimétrica
Um algoritmo assimétrico envolve duas chaves. Uma chave pública e outra chave privada. Enquanto uma chave (privada) é usada para assinar digitalmente a mensagem a outra chave (pública) só pode ser usada para verificar a autenticidade da assinatura.
IdentityServer4 - JWK & JWKS
O IdentityServer4, assim como outros providers de OAuth 2.0, utiliza o JWT para geração de Bearer tokens. Um dos motivos para utilizar o JWT é que ele possui conceitos de JWK e JWKS. É por causa desses dois conceitos que é possível compartilhar o JWT entre as diversas aplicações com segurança.
Json Web Key (JWK)
JWK é uma estrutura JSON que representa uma chave de criptografia. Na sua estrutura contém as informações para criptografar um JWT (JWE) ou Assinar Digitalmente (JWS).
Dentro de um ambiente OAuth 2.0, o responsável por criar e gerenciar o JWK é o Authorization Server. Como no OAuth 2.0 todos os JWT's são emitidos por um único servidor ele é quem gerencia o JWK. Assim somente o Authorization Server pode emitir um JWT.
Certos parâmetros do JWK podem ser públicos, dessa forma os consumidores do JWT podem validar se o JWT não foi adulterado.
Exemplo de um JWK público (Google):
Exemplo de um JWK privado:
Json Web Key Set (JWKS)
JWKS é um array de JWK.
Os algoritmos de criptografia se tornam mais fracos com o tempo. Seja por que as técnicas de análise de criptografia melhoram ou por causa do desempenho dos computadores que melhoram dia após dias. Ambos contribuem para diminuir o tempo necessário para quebrar um algoritmo específico. Portanto, o objetivo do JWK e JWKS é permitir que um servidor OAuth 2.0 seja modular em relação a criptografia. Permitindo que novos algoritmos sejam facilmente inseridos.
Por esse motivo as boas práticas dizem que o JWK deve mudar a cada 90 dias. E com o auxilio do JWKS, ao efetuar a troca do algoritmo, não irá invalidar os tokens que foram gerados com o algoritmo anterior. Permitindo uma troca gradual, sem afetar os sistemas.
Atualmente o OAuth 2.0 utiliza o mesmo JWK para assinar o access_token e o identity_token. Há uma discussão no OAuth Working Group sobre separar a responsabilidade. Em breve teremos novidades.
Todo servidor OAuth 2.0 mantém um link público de seus JWKS.
Exemplo de um JWKS público Google:
Repare que apesar de público, não possui os dados privados. Utilizado para assinar o JWT.
Por que é importante?
Os demos e samples do IdentityServer4 não são bons exemplos para subir em produção. Além da segurança com o correto gerenciamento das chaves de criptografia. Você eventualmente terá problemas em situações de Load Balance, quando precisar escalar seu servidor de IdentityServer4.
Se a chave do seu JWT vazar, um usuário mal intencionado consegue impersonar qualquer usuário e ter acesso a qualquer API.
A documentação menciona a importância do Key Material, mas não dá detalhes sobre como gerenciar corretamente. Então se ninguém no time fez a configuração correta. Terá que contar com a sorte. Pois nem todos materiais disponíveis na internet leva em consideração cenários de Load Balance.
Como gerenciar o Key Material do IdentityServer4
O IdentityServer4 provê a extensão AddSigningCredential()
e AddValidationKey()
. A primeira é responsável por adicionar a Chave de Criptografia principal. E será utilizado para assinar digitalmente seu JWT.
Ao adicionar uma chave ao IdentityServer pela primeira vez, por exemplo chave1, você utilizr o AddSigningCredential()
. E pode manter em produção por um certo período de tempo. 90 dias, 1 ou 2 anos.
Após esse período, é necessário preparar a chave2, para substituir a anterior. No entanto, se mudar imediatamente haverá bugs com os Clients e API's que ainda estão fazendo o cachê da chave1. Invalidando as requisições e eventualmente deslogando seu usuário. Por isso é necessário é introduzir a chave1 no discovery document antes de tornar a chave2 principal.
O OAuth 2.0 disponibiliza o endpoint /.well-known/openid-configuration/jwks
. O primeiro item do Array corresponde a chave ativa. Os demais são as chaves anteriores. A extensão AddValidationKey()
é a responsável por adicionar as chaves anteriores.
Veja um exemplo de como irá ficar o jwks
endpoint.
O mais importante aqui é que a Chave utilizada deverá ser a mesmas entre todas as instâncias do AuthServer.
Estratégia para gerenciar as chaves
O objetivo final é o mesmo: Garantir que a mesma chave será utilizada em todas as instâncias. Sem abrir mão da segurança da chave. Afinal, se ela cair em mãos erradas, essa pessoa teria capacidade de gerar qualquer JWT e se passar por qualquer usuário. Isso seria desastroso.
IdentityServer Key Management
Esse é um produto oficial do IdentityServer4. Custa uma bagatela de €3.000,00. E você teria suporte oficial.
Azure Key Vault / AWS KMS
É possível utilizar o Azure Key Vault ou Amazon KMS para armazenar um certificado auto gerado. Para quem pretende utilizar certificados autogerados considero a melhor opção, devido à natureza da segurança de armazenamento.
JWKS.Manager
É uma biblioteca Open Source, que é uma alternativa direta ao IdentityServer Key Management. Sua arquitetura foi baseado no componente Microsoft.AspNetCore.DataProtection e possui uma extensão que implementa as interfaces ISigningCredentialStore
e IValidationKeysStore
do IdentityServer4.
Se você olhar no código fonte do IdentityServer4, ele implementa essas interfaces com os objetos InMemorySigningCredentialsStore
e InMemoryValidationKeysStore
, respectivamente.
A biblioteca segue as melhores práticas recomendados pelas RFC 7518 e RFC 7517. E também segue as recomendações do NIST.
Evite utilizar essas estratégias
Algumas estratégias parecem boas, mas não são aconselháveis.
Azure Blob store - Amazon S3
Ao armazenar o certificado em um Blob Store ou Amazon S3 ao invés do Azure Key Vault ou KMS. A diferença, recai na segurança, pois esses serviços não tem como premissa a segurança do arquivo.
Gerar uma imagem Docker com o arquivo embutido
Uma estratégia que alguns times fazem é gerar uma imagem docker com o arquivo dentro.
O problema dessa prática é na renovação das chaves de criptografia. O recomendado é renovar a cada 90 dias. Manter a chave anterior disponível por um período. E remover as partes privadas das chaves anteriores.
Conclusão
Espero que esse material te ajude mais do que o material oficial do IdentityServer4. Ele carece de exemplos e estratégias. Até mesmo de informações que guiem o seu time ao produto oficial deles (Key Management). E esse assunto pode gerar grande dor de cabeça em times que possuem o IdentityServer4 em produção.
Comments