Cifrado de archivo de configuración

Antecedentes


Tengo la tarea de configurar CI. Se decidió utilizar la transformación de los archivos de configuración y almacenar datos confidenciales en forma cifrada. Puede encriptarlos y desencriptarlos utilizando Key Container.

Contenedor clave


Cada sistema operativo Windows tiene conjuntos de claves generadas. La clave se genera en la cuenta o en la máquina. Las claves generadas por la máquina se pueden ver a lo largo de esta ruta C: \ ProgramData \ Microsoft \ Crypto \ RSA \ MachineKeys. Aquí es donde irá la clave que crearemos a continuación.

Creación de claves


Comenzamos cmd desde el administrador y cambiamos al directorio con aspnet_regiis, tengo este C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319

Ejecutar el comando

aspnet_regiis -pc "TestKey" -exp 

exp: se agrega para que pueda exportar la clave en el futuro
TestKey: el nombre de nuestro contenedor de claves

Exportación clave


El equipo

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

TestKey - nombre del contenedor de claves
C: \ TestKey.xml: la ruta donde se exportará el archivo
pri: agrega una clave privada para exportar

Clave de importación


El equipo

 aspnet_regiis -pi "TestKey" :\TestKey.xml 

TestKey - nombre del contenedor de claves
C: \ TestKey.xml: la ruta desde donde se exportará el archivo

Establecer derechos


Para que su aplicación o IIS funcione con el contenedor de claves, debe configurar los derechos para ello.

Esto lo hace el equipo

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

TestKey - nombre del contenedor de claves
NT AUTHORITY \ NETWORK SERVICE: quién tendrá acceso a la clave

De manera predeterminada, IIS tiene ApplicationPoolIdentity para el grupo.

La documentación de Microsoft (ver enlace 2) describe ApplicationPoolIdentity como:

  • ApplicationPoolIdentity : cuando se crea un nuevo grupo de aplicaciones, IIS crea una cuenta virtual que tiene el nombre del nuevo grupo de aplicaciones y que ejecuta el proceso de trabajo del grupo de aplicaciones en esta cuenta. Esta es también una cuenta menos privilegiada.

Por lo tanto, para que IIS pueda descifrar la configuración, Identity debe configurarse en el grupo para la cuenta, o puede seleccionar "SERVICIO DE RED" y otorgarle derechos.

Agregar una sección a la configuración


 <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> 

También el contenedor de claves y RsaProtectedConfigurationProvider se definen globalmente en archivos

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> 

Cifrado


El cifrado en sí se puede hacer de tres maneras.

Cifrado de línea de comando


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

C: \ Site: ruta al archivo con la configuración.

CustomRsaProtectedConfigurationProvider: nuestro proveedor especificado en la configuración llamada contenedor de claves.

Cifrado a través de una aplicación escrita.


 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


Cuando hay una transformación de archivo y necesita cifrar secciones por separado de toda la configuración, solo es adecuada una versión autoescrita. Creamos una instancia de la clase RsaProtectedConfigurationProvider, tomamos un nodo de xml y lo ciframos por separado, luego reemplazamos el nodo en nuestro xml original con nuestro cifrado y guardamos el 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); } } 

Referencias


1.docs.microsoft.com/en-us/previous-versions/53tyfkaw
2.support.microsoft.com/en-za/help/4466942/understanding-identities-in-iis

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


All Articles