Criptografia de arquivo de configuração

Antecedentes


Eu tenho a tarefa de configurar o CI. Decidiu-se usar a transformação dos arquivos de configuração e armazenar dados confidenciais em formato criptografado. Você pode criptografar e descriptografá-los usando o Key Container.

Recipiente chave


Cada sistema operacional Windows possui conjuntos de chaves geradas. A chave é gerada na conta ou na máquina. As chaves geradas pela máquina podem ser exibidas nesse caminho C: \ ProgramData \ Microsoft \ Crypto \ RSA \ MachineKeys. É aqui que a chave que criaremos a seguir irá.

Criação de chave


Começamos o cmd a partir do administrador e alternamos para o diretório com aspnet_regiis, tenho este C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319

Execute o comando

aspnet_regiis -pc "TestKey" -exp 

exp - é adicionado para que você possa exportar a chave no futuro
TestKey - o nome do nosso Key Container

Exportação de chaves


A equipe

 aspnet_regiis -px "TestKey" :\TestKey.xml -pri 

TestKey - nome Key Container
C: \ TestKey.xml - o caminho para o qual o arquivo será exportado
pri - adicione uma chave privada para exportar

Chave de importação


A equipe

 aspnet_regiis -pi "TestKey" :\TestKey.xml 

TestKey - nome Key Container
C: \ TestKey.xml - o caminho de onde o arquivo será exportado

Definir direitos


Para que seu aplicativo ou IIS funcione com o contêiner de chaves, você precisa configurar os direitos para ele.

Isso é feito pela equipe

 aspnet_regiis -pa "TestKey" "NT AUTHORITY\NETWORK SERVICE" 

TestKey - nome Key Container
NT AUTHORITY \ NETWORK SERVICE - a quem será concedido acesso à chave

Por padrão, o IIS tem ApplicationPoolIdentity para o pool.

A documentação da Microsoft (consulte o link 2) descreve ApplicationPoolIdentity como:

  • ApplicationPoolIdentity : quando um novo pool de aplicativos é criado, o IIS cria uma conta virtual com o nome do novo pool de aplicativos e que executa o processo de trabalho do pool de aplicativos nessa conta. Essa também é uma conta com menos privilégios.

Portanto, para que o IIS possa descriptografar a configuração, a Identidade deve estar configurada no pool da conta ou você pode selecionar "SERVIÇO DE REDE" e conceder direitos a ela.

Adicionando uma seção à configuração


 <configProtectedData defaultProvider="RsaProtectedConfigurationProvider"> <providers> <add name="CustomRsaProtectedConfigurationProvider" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="TestKey" cspProviderName="" useMachineContainer="true" useOAEP="false"/> </providers> </configProtectedData> 

Também o contêiner de chaves e o RsaProtectedConfigurationProvider são definidos globalmente nos arquivos

C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ Config \ machine.config, C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ Config \ machine.config

 <configProtectedData defaultProvider="RsaProtectedConfigurationProvider"> <providers> <add name="RsaProtectedConfigurationProvider" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="NetFrameworkConfigurationKey" cspProviderName="" useMachineContainer="true" useOAEP="false"/> <add name="DataProtectionConfigurationProvider" type="System.Configuration.DpapiProtectedConfigurationProvider,System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses CryptProtectData and CryptUnProtectData Windows APIs to encrypt and decrypt" useMachineProtection="true" keyEntropy=""/> </providers> </configProtectedData> = "System.Configuration.DpapiProtectedConfigurationProvider, System.Configuration, versão = 4.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a" description = "Usa CryptProtectData e CryptUnprotectData do Windows APIs para criptografar e descriptografar" useMachineProtection = <configProtectedData defaultProvider="RsaProtectedConfigurationProvider"> <providers> <add name="RsaProtectedConfigurationProvider" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="NetFrameworkConfigurationKey" cspProviderName="" useMachineContainer="true" useOAEP="false"/> <add name="DataProtectionConfigurationProvider" type="System.Configuration.DpapiProtectedConfigurationProvider,System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses CryptProtectData and CryptUnProtectData Windows APIs to encrypt and decrypt" useMachineProtection="true" keyEntropy=""/> </providers> </configProtectedData> 

Criptografia


A criptografia em si pode ser feita de três maneiras.

Criptografia de linha de comando


 aspnet_regiis.exe -pef connectionStrings :\Site -prov "CustomRsaProtectedConfigurationProvider" 

C: \ Site - caminho para o arquivo com a configuração.

CustomRsaProtectedConfigurationProvider - nosso provedor especificado na configuração chamada key container.

Criptografia através de um aplicativo escrito


 private static string provider = "CustomRsaProtectedConfigurationProvider"; public static void ProtectConfiguration() { Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); ConfigurationSection connStrings = config.ConnectionStrings; if (connStrings != null && !connStrings.SectionInformation.IsProtected && !connStrings.ElementInformation.IsLocked) { connStrings.SectionInformation.ProtectSection(provider); connStrings.SectionInformation.ForceSave = true; config.Save(ConfigurationSaveMode.Full); } } public static void UnProtectConfiguration(string path) { Configuration config = ConfigurationManager.OpenExeConfiguration(path); ConfigurationSection connStrings = config.ConnectionStrings; if (connStrings != null && connStrings.SectionInformation.IsProtected && !connStrings.ElementInformation.IsLocked) { connStrings.SectionInformation.UnprotectSection(); } } 

Bicicleta


Quando houver uma transformação de arquivo e você precisar criptografar seções separadamente de toda a configuração, apenas uma versão auto-escrita será adequada. Criamos uma instância da classe RsaProtectedConfigurationProvider, pegamos um nó do xml e o criptografamos separadamente, depois substituímos o nó no nosso xml original pelo nosso criptografado e salvamos o resultado.

 public void Protect(string filePath, string sectionName = null) { XmlDocument xmlDocument = new XmlDocument { PreserveWhitespace = true }; xmlDocument.Load(filePath); if (xmlDocument.DocumentElement == null) { throw new InvalidXmlException($"Invalid Xml document"); } sectionName = !string.IsNullOrEmpty(sectionName) ? sectionName : xmlDocument.DocumentElement.Name; var xmlElement = xmlDocument.GetElementsByTagName(sectionName)[0] as XmlElement; var config = new NameValueCollection { { "keyContainerName", _settings.KeyContainerName }, { "useMachineContainer", _settings.UseMachineContainer ? "true" : "false" } }; var rsaProvider = new RsaProtectedConfigurationProvider(); rsaProvider.Initialize(_encryptionProviderSettings.ProviderName, config); var encryptedData = rsaProvider.Encrypt(xmlElement); encryptedData = xmlDocument.ImportNode(encryptedData, true); var createdXmlElement = xmlDocument.CreateElement(sectionName); var xmlAttribute = xmlDocument.CreateAttribute("configProtectionProvider"); xmlAttribute.Value = _encryptionProviderSettings.ProviderName; createdXmlElement.Attributes.Append(xmlAttribute); createdXmlElement.AppendChild(encryptedData); if (createdXmlElement.ParentNode == null || createdXmlElement.ParentNode.NodeType == XmlNodeType.Document || xmlDocument.DocumentElement == null) { XmlDocument docNew = new XmlDocument { InnerXml = createdXmlElement.OuterXml }; docNew.Save(filePath); } else { xmlDocument.DocumentElement.ReplaceChild(createdXmlElement, xmlElement); xmlDocument.Save(filePath); } } 

Referências


1.docs.microsoft.com/pt-br/previous-versions/53tyfkaw
2.support.microsoft.com/pt-br/help/4466942/understanding-identities-in-iis

Source: https://habr.com/ru/post/pt462379/


All Articles