ASP.NET 2.0 - Cifrando informações nos arquivos de configuração


A ASP.NET armazena toda a informação de configuração em arquivos textos chamados web.config e machine.config. Desta forma toda a informação vital incluindo strings de conexão para banco de dados , senhas , nome de usuários , etc. Você não acha que esta é uma forma muito vulnerável de guardar informação de tamanha importância ?

É claro que se você deixar toda esta informação armazenada nos arquivos textos ela estará vulnerável e passível de ser acessada por pessoas mal intencionadas.

Mas não se alarme , pensando nisso , a Microsoft disponibilizou a partir da versão 2.0 da ASP.NET a capacidade de você poder cifrar (encriptar) esta informação. Usando estes novos recursos você pode facilmente cifrar seções de configurações para tornar a sua aplicação mais segura. Não esqueça porém que existe o custo de cifrar e decifrar as seções que você cifrou e isto pode afetar o desempenho de sua aplicação. Portanto use este recurso com parcimônia.

A partir da ASP.NET 2.0 temos o modelo de protegido de configuração que permite a cifragem dos dados usando dois provedores de configuração protegida: São eles:

Explorando os novos recursos para Cifrar e decifrar dados nos arquivos de configuração

Vamos mostrar a seguir um exemplo de como podemos usar estes recursos para cifrar e decifrar as strings de conexão com o banco de dados armazenadas no arquivo web.config.

Selecione um arquivo web.config no qual exista uma string de conexão para um banco de dados em um projeto já existente. Abaixo temos um exemplo de um arquivo web.config exibindo a seção de configuração para a string de conexão e a string de conexão usada:

<configuration>
<appSettings/>
<connectionStrings>
<add name="clientesConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=C:\_aspn\artigos\App_Data\clientes.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>

Observe a seção <connectionStrings> no exemplo acima o qual contém a informações sobre a string de conexão. Abra então o projeto e selecione o arquivo Default.aspx que neste caso é o formulário web principal da aplicação.

Vamos usar o modelo RSAProtectedConfigurationProvider para cifrar a string de conexão. Para isto inclua o código abaixo via code-behind no arquivo Default.aspx.vb :

Imports System.Web.Configuration
Imports System.Web.Security
Imports System.Configuration

Public Sub cifrarStringConexao()

Dim config As Configuration = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath)
Dim section As ConfigurationSection = config.GetSection("connectionStrings")

If Not section.SectionInformation.IsProtected Then
        section.SectionInformation.ProtectSection("
RsaProtectedConfigurationProvider")
        config.Save()
End If

End Sub

A seguir no evento Load da página inclua a chamada a rotina de cifragem:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
       cifrarStringConexao()
End Sub

Vamos entender o código acima:

O namespace System.Configuration contém as classes que tratam a informação de configuração associada com a aplicação cliente e a aplicação ASP.NET.

A classe WebConfigurationManager é fornece o acesso aos arquivos de configuração das aplicações ASP.NET. Podemos usar o método OpenWebConfiguration() para retornar um objeto de configuração, o qual fornece os métodos e propriedades necessários para tratar com a informação dos arquivos de configuração.

O método GetSection do objeto de configuração retorna o objeto connectionStrings para o arquivo web.config.

<configuration>
<appSettings/>
<connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider">
<EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyName>Rsa Key</KeyName>
</KeyInfo>
<CipherData>
<CipherValue>BAkxwETQO3saW0aEv94UWsntT2JZhkyeNGD1DN7ndY7S8nLwufR/_
E9MPC42worV0s888jvlOqXt5QZ77UjrD9GijiFrzUpUTRDJrYWWQRHJAtNHcVuvQgnA2oLIa6hQck3wC1mGujBNeuZU9/1QHBIcK5GUXINcvHkx8Yul/sZI=</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
<CipherValue>rW0x+dmTNPMNTvB2VniY5aS6IfYlC4NJ4wtPROrf94IXS/yhPlZ+u60hk6jTdgawWYIH8QcoyqbKKDH8smk6_
NixKuByFEuma3kL17piFS+VbvfARibKSKFLzpZPovv224TfXO0hACfyEZxH0zuy/4RGzMu5uSod/pDIADER3h8jHTIAihdFMk+_
tezOb7kh9T5+MNuWMVF4s8RFtEGhGkZN23hDgfJNbQSIhl+l5a+aUzt4Fe5KHXnHrNYKKbAijwKOfGbfgfyrTk9ll+aJCgXV5N_
qc5iQeKbxgkQ32QYzfzs3Dm1Zz85ng8QkkX2UfS7MAOgOTg6xbRfLrj0Nd1qZ4GgawluVVjCJdihAy2MRW4pAFwXoI8uWRVSy7qR7QSPyrMkkF6IvPY=</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
<system.web>

Da mesma forma podemos cifrar a informação da string de conexão usando o modelo DataProtectionConfigurationProvider. Usando o mesmo método acima vamos apenas substitituir o parâmetro para o método ProtectSection de RsaProtectedConfigurationProvider para DataProtectionConfigurationProvider. O código ficaria assim:

Imports System.Web.Configuration
Imports System.Web.Security
Imports System.Configuration

Public Sub cifrarStringConexao()

Dim config As Configuration = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath)
Dim section As ConfigurationSection = config.GetSection("connectionStrings")

If Not section.SectionInformation.IsProtected Then
        section.SectionInformation.ProtectSection("
DataProtectionConfigurationProvider")
        config.Save()
End If

End Sub

Reconstruindo a página web e executando o projeto iremos obter o seguinte resultado para o arquivo web.config.

<configuration>
<appSettings/>
<connectionStrings configProtectionProvider="DataProtectionConfigurationProvider">
<EncryptedData>
<CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAfLSIEYs4v0eGTazWqS/VcAQAAAACAAAAAAADZgAAqAAAABAAAA
DHTE0j8+WCxG+s0dD45t10AAAAAASAAACgAAAAEAAAAP8ehFFi2fpHBWbm03UUi4hAAgAAO0lV+SQWUgxDsMVbr5o0lcm9kpz
T86vaifFPEiLtHmRBkrLx5L/wjiEdmnzRFrV8tyLLkqsBNhcFMATyoIPtz6twC2y9q75nmxlMAEAJEJ364gC/0O1g58etUgPQvEeQOhDBbYWJ
7LjNr6Iu8cN0oFOLhxsAGLhdaKySf7HTyGgBpTJQe/yKXmP0yXlQcxm2cJoPjPAQ136nHDwbjUoIml/33mj6LArLjpCiL+62favMNuREIQQN
Io6td7e8pPKU8F0TvVrDETLkh5lKgk7q3j1/aAiTN54+NKMihUS5rhFHdJKTDeQrx4WLowPLAtskVdvHL/I/IVtCeHCa5DW8C9qw4RV4Q
ux8c+PqXvhQhYTKn+3EoDMy++JDz6OxrZAtofSiww9UoIs5TlzxX+5YhUdRVscA5hMP0d6LKjoYoSxMoTqpIPq7wWFw/oKgz0TDxYXD/
wv3gIzDz7k1Vm2jSMw5WmPI5w/0ERKWDKbmzdO12INmzk8lgS+oBq4Fic/syU6z+qr0xdXe5ImjgnkBE4p5ewIDEZB1HJ4COGZMiWlj7
vgktlzscPZyK61r/EuqXxWY8ay6VATK6EVYIhEoVYytZK3O6e3a1oD0EMCtsRkSJwTUdbx9MisafDMKk6cmOaYhoYZnWM+AtdkgrtUpHD
pt2WMEwP5jAb6Bw8ZzzjNEmuaws0x6M+XhrK47PDyCKn8LzINT9qVYYckYwlxOd8KbrmB/Cm9egay6lEhTBq0aRw1He5L3WbSxo55/B9Q
7FAAAAJRpvJ4cTHtzY1Dtb7FynFqEHR1a</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
<system.web>

Para efetuar o processo inverso e decifrar a string de conexão vamos criar o método decifrarStringConexao():

Public Sub decifrarStringConexao()

Dim config As Configuration = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath)
Dim section As ConfigurationSection = config.GetSection("connectionStrings")

If section.SectionInformation.IsProtected Then
    section.SectionInformation.UnprotectSection()
    config.Save()
End If

End Sub

Lembre-se que não podemos cifrar todas as seções do arquivo web.config usando o código acima. As seções a seguir necessitam de um tratamento adicional antes de podermos efetuar a cifragem:

Para poder efetuar a cifragem destas seções de configurações você precisa cifrar o valor e armazenar no registro do sistema. Existe uma ferramenta de linha de comando que pode ajudá-lo nesta tarefa.

Usando o utilitário aspnet_regiis.exe para cifrar e decifrar

Podemos também usar a ferramenta para linha de comando aspnet_regiis.exe para cifrar e decifrar seções em um arquivo web.config. Você pode encontrar o utilitário na pasta <WINDOWSDIR>\Microsoft.Net\Framework\version. (Na minha máquina o caminho é C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727)

Veja também o artigo: ASP.NET - Usando a ferramenta ASPNET_REGIIS.EX

Para cifrar uma seção do arquivo web.config usando chave DPAPI machine com este utilitário execute o seguinte comando:

aspnet_regiis  -pe  "connectionStrings"  -app  "/NomeDoSeuWebSite"   -prov  "DataProtectionConfigurationProvider"

Vejamos o significado dos parâmetros usados:

Para decifrar a seção connectionStrings usando o utilitário, você pode especificar o seguinte comando:

aspnet_regiis  -pd "connectionStrings" -app "/NomeDoSeuWebSite"

-pd = o argumento para decifragem usado para o utilitário aspnet_regii;

Embora a ASP.NET esteja configurada para rejeitar todas as requisições HTTP para recursos com a extensão .config se um usuário mal intencionado obter acesso aos arquivos de configuração do sistema do servidor a informação contida nos arquivos de configuração estará desprotegida.

Felizmente a ASP.NET 2.0 mitiga este problema pela introdução de esquemas de cifragem para arquivos de configuração. Você pode então cifrar/decifrar arquivos de configuração incluindo os arquivos web.config e Machine.config quer seja via código quer seja usando o utilitário aspnet_regiis.exe.

Eu sei é apenas ASP.NET, mas eu gosto..