Contexte
J'ai eu la tâche de configurer CI. Il a été décidé d'utiliser la transformation des fichiers de configuration et de stocker les données confidentielles sous forme cryptée. Vous pouvez les chiffrer et les déchiffrer à l'aide du conteneur de clés.
Conteneur à clés
Chaque système d'exploitation Windows possède des ensembles de clés générées. La clé est générée soit sur le compte, soit sur la machine. Les clés générées par la machine peuvent être affichées le long de ce chemin C: \ ProgramData \ Microsoft \ Crypto \ RSA \ MachineKeys. C'est là que la clé que nous allons créer ensuite ira.
Création de clé
Nous démarrons cmd depuis l'administrateur et basculons vers le répertoire avec aspnet_regiis, je l'ai C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319
Exécutez la commande
aspnet_regiis -pc "TestKey" -exp
exp - est ajouté afin que vous puissiez exporter la clé à l'avenir
TestKey - le nom de notre conteneur de clés
Exportation de clé
L'équipe
aspnet_regiis -px "TestKey" :\TestKey.xml -pri
TestKey - nom Key Container
C: \ TestKey.xml - le chemin où le fichier sera exporté
pri - ajouter une clé privée à exporter
Clé d'importation
L'équipe
aspnet_regiis -pi "TestKey" :\TestKey.xml
TestKey - nom Key Container
C: \ TestKey.xml - le chemin à partir duquel le fichier sera exporté
Définition des droits
Pour que votre application ou IIS fonctionne avec le conteneur de clés, vous devez configurer les droits pour celui-ci.
Cela se fait par l'équipe
aspnet_regiis -pa "TestKey" "NT AUTHORITY\NETWORK SERVICE"
TestKey - nom Key Container
AUTORITÉ NT \ SERVICE RÉSEAU - qui aura accès à la clé
Par défaut, IIS a ApplicationPoolIdentity pour le pool.
La documentation Microsoft (voir lien 2) décrit ApplicationPoolIdentity comme suit:
ApplicationPoolIdentity : lorsqu'un nouveau pool d'applications est créé, IIS crée un compte virtuel qui porte le nom du nouveau pool d'applications et qui exécute le processus de travail du pool d'applications sous ce compte. Il s'agit également d'un compte le moins privilégié.
Par conséquent, pour qu'IIS puisse déchiffrer la configuration, l'identité doit être configurée dans le pool pour le compte, ou vous pouvez sélectionner "SERVICE RÉSEAU" et lui donner des droits.
Ajout d'une section Ă la configuration
<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>
Le conteneur de clés et RsaProtectedConfigurationProvider sont également définis globalement dans les fichiers
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.RsaProtectedConfigurationProvider, System.Configuration, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a" Description = "Utilise RSACryptoServiceProvider pour crypter et décrypter" keyContainerName = "NetFrameworkConfigurationKey" cspProviderName <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>
Cryptage
Le cryptage lui-même peut être effectué de trois manières.
Chiffrement de la ligne de commande
aspnet_regiis.exe -pef connectionStrings :\Site -prov "CustomRsaProtectedConfigurationProvider"
C: \ Site - chemin d'accès au fichier avec la configuration.
CustomRsaProtectedConfigurationProvider - notre fournisseur spécifié dans la configuration appelée conteneur de clés.
Cryptage via une application écrite
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(); } }
Vélo
Lorsqu'il y a une transformation de fichier et que vous devez crypter des sections séparément de la configuration entière, alors seule une version auto-écrite convient. Nous créons une instance de la classe RsaProtectedConfigurationProvider, prenons un nœud de XML et le chiffrons séparément, puis remplaçons le nœud dans notre XML d'origine par notre chiffré et enregistrons le résultat.
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); } }
Les références
1.docs.microsoft.com/en-us/previous-versions/53tyfkaw2.support.microsoft.com/en-za/help/4466942/understanding-identities-in-iis