ASP.NET Core 3.1 - IdentityServer4 - Segurança (Parte 2)

Atualização

Ao finalizar a leitura deste post, sugiro você conferir algumas mudanças que ocorreu após a publição original. As mudanças estão no post ASP.NET Core 3.1 - IdentityServer4 - Segurança - Atualização.

OpenSSL

Vamos começar pela instalação do OpenSSL, nos próximos tópicos ficará mais claro como a configuração de segurança do IdentityServer vai funcionar.

Siga os passos a seguir:

  • Baixe o OpenSSL. Após instalar recomendo reiniciar o computador.
  • Abra o PowerShell e execute o OpenSSL de dentro da pasta bin onde ele foi instalado conforme imagem a seguir. Isso é necessário para que não gere erro na execução dos comandos por não encontrar seu arquivo de configuração, existem outras formas de fazer, mas esta é a mais simples. OpenSSL
  • OpenSSL> genrsa -des3 -out private.pem 2048

private.pem: nome do arquivo que vai ser gerado onde o conteúdo é a chave privada.

2048: número de bits da chave privada. Poderia ser 1024, mas o Azure e a documentação sugere 2048.

Enter pass phrase for private.pem: digite uma senha para sua chave privada. Verifying - Enter pass phrase for private.pem: digite novamente a mesma senha.

  • OpenSSL> rsa -in private.pem -outform PEM -pubout -out public.pem

public.pem: a partir da chave privada, você vai extrair a chave pública que ficará armazenada neste arquivo.

Enter pass phrase for private.pem: digite a senha da chave privada, a mesma informada no passo anterior, somente com ela você vai conseguir obter a chave pública.

  • OpenSSL> req -x509 -sha256 -nodes -days 720 -key private.pem -out certificate.crt

Com este comando, geramos o arquivo certificate.crt e através dele já é possível instalar o certificado. O certificado é gerado com validade de 720 dias, novamente utilizamos a chave privada para geração do certificado e você vai precisar novamente informar a senha criada nos passos anteriores. Tudo isso por questão de segurança, nunca gere um certificado sem senha.

Você ainda vai poder informar dados que ficarão contidos no certificado:

Country Name (2 letter code) [AU]:BR
State or Province Name (full name) [Some-State]:Santa Catarina
Locality Name (eg, city) []:Florianopolis
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Nome da empresa
Organizational Unit Name (eg, section) []:sigla da empresa
Common Name (e.g. server FQDN or YOUR name) []:seu nome
Email Address []:seu e-mail

  • OpenSSL> pkcs12 -export -out certificate.pfx -inkey private.pem -in certificate.crt

Por último, iremos gerar o arquivo certificate.pfx que possui todas as informações do certificado (digitadas anteriormente), este é o certificado do tipo A1 que utilizaremos para criptografar o token (payload) gerado pelo IdentityServer e que você precisa para colocar em ambiente diferente de Development.

Durante a geração será solicitada a senha da chave privada e depois vai solicitar que você crie uma senha que será utilizada na instalação do certificado, no uso ou na exportação dos dados conforme abaixo.

Enter pass phrase for private.key: senha da chave privada

Enter Export Password: crie uma senha de exportação.

Verifying - Enter Export Password: digite novamente a mesma senha de exportação.

Instalando o certificado digital

Clique com o botão direito sobre o arquivo certificate.pfx (ou duplo clique) selecione a opção Install PFX.
Você pode instalar o certificado para que somente o seu usuário (logado no windows no momento) tenha acesso ou então instalar para ser válido para todos os usuários LocalMachine, siga os passos até a hora que a senha for solicitada, neste momento, você deve utilizar a senha de exportação para instalar o certificado.

Possibilidades de uso

Primeiramente lembre-se que esse processo somete é necessário para o funcionamento em produção (diferente de Development), seja configurado no IIS, seja no Azure ou até mesmo no Docker.
O IdentityServer permite algumas possibilidades de configuração do certificado digital:

  • Uso do thumbprint;
  • Uso do *.pfx de forma direta, este caso é mais utilizado para o funcionamento da aplicação em um container do Docker;
  • Maquear a obrigatoriedade do uso de um certificado digital do tipo A1. Perceba com muito cuidado que "maquear" nunca é uma boa alternativa, pois sabemos que tudo que é provisório vira definitivo em pouco tempo. Esta prática eu sugeriria para casos que você não pode aguardar a compra de um certificado oficial, não quer usar um certificado fake (gerado pelo OpenSSL) e que seu processo de autenticação e autorização com token não é algo crítico para o seu negócio, porém nunca esqueça que estamos falando de segurança e nunca no mundo da internet de alguns anos pra cá este assunto está sendo tão amplamente discutido.

Thumbprint

Também denominado de "impressão digital", é uma propriedade do certificado digital e esta propriedade é utilizada para que o IdentityServer encontre o certificado digital.

Através do PowerShell, com os comandos a seguir, você pode encontrar o thumbprint do certificado digital que você gerou e instalou no PC.

PS> Get-ChildItem -path cert:\LocalMachine\My
PS> Get-ChildItem -path cert:\CurrentUser\My

A imagem a seguir exemplifica o certificado digital que foi gerado e o thumbprint que será utilizado no código.

Thumbprint

O código a seguir pertence ao Statup.cs (pode ser conferido também no GitHub), onde passamos como parâmetro o thumbprint. Perceba que se o ambiente for Development, será utilizado o modo padrão de desenvolvimento do software e quando for Production ou Staging será utilizado o certificado instalado.

if (_webHostEnvironment.IsDevelopment())  
    identityServer.AddDeveloperSigningCredential();
else  
    identityServer.AddSigningCredential("4DFF9B8EBB5314B9A62EFA72DA8B4D7658231C05", StoreLocation.CurrentUser, NameType.Thumbprint);

Se você está utilizando o App Services do Azure, você pode instalar o certificado digital diretamente nas configurações de SSL, desde que o Service Plan não seja o free nem o shared, isso vai elevar um pouco o custo de manter o serviço rodando. Ao realizar o upload do certificado digital, você vai precisar especificar a senha de exportação e o Azure vai disponibilizar o thumbprint para você utilizar no seu código.

Uso do *.pfx direto

Caso você não queira instalar o certificado digital A1 (*.pfx), você pode usar o arquivo de forma direta. Mas atenção, neste caso você precisará expor a senha de exportação do certificado digital, aquela que você usou quando falamos sobre a instalação.

if (_webHostEnvironment.IsDevelopment())  
    identityServer.AddDeveloperSigningCredential();
else  
    identityServer.AddSigningCredential(new X509Certificate2("certificate.pfx", "senha"));

Este caso é a forma mais simples de usar no Docker, onde o arquivo do certificado digital fica dentro do container onde a aplicação está rodando.

Forma de uso maqueado

Este método de uso eu não recomendo pelos motivos que comentei anteriormente, o provisório vai virar definitivo, sempre vira, mas quem se garantir, use para testes rápidos em ambiente Staging por exemplo.

Para este caso, foi criado um método de extensão ou extension method como é mais conhecido. O método "AddCustomSigningCredential()" usa o arquivo tempkey.rsa que falamos no post ASP.NET Core 3.1 - IdentityServer4 - In-memory (Parte 1)

A seguir um trecho de código que você vai encontrar no GitHub.

using IdentityServer.Extensions;

if (_webHostEnvironment.IsDevelopment())  
    identityServer.AddDeveloperSigningCredential();
else  
    identityServer.AddCustomSigningCredential();

Em caso de dúvida você pode baixar o projeto que está do GitHub.

PS: Este projeto está em constante evolução, inicialmente a ideia é que o conteúdo seja entendido, tem código fixo que poderiam vir de um user secret ou até mesmo do appsettings.json, mas não é uma preocupação neste momento.

Continua em ASP.NET Core 3.1 - IdentityServer4 - API de Pagamento (Parte 3).