Visual Studio - Protéger une chaine de connexion

L'approche recommandée pour stocker une chaine de connexion à une base de données est d'utiliser le fichier de configuration du programme (app.config). Mais cela entraine un problème au niveau de la sécurité des données. En effet, le mot de passe utilisé pour la connexion à la base se retrouve en clair dans le fichier XML.

Pour pallier à ce problème, il est possible de chiffrer la section connectionStrings en suivant les instructions détaillées sur cet article de MSDN.

En utilisant le code fourni, on peut générer un petit exécutable en ligne de commande. Ce programme peut ensuite être appelé à chaque génération de notre application en utilisant la ligne de commande après génération des options du projet.

Après génération

Dans l'exemple ci-dessus, j'ai placé mon utilitaire EncryptCfg.exe dans le sous-répertoire EncryptCfg\bin\Release\ de ma solution. Je passe en argument le chemin complet de ma cible (.exe ou .dll).

Avant l'opération de chiffrage, le fichier .config ressemble à ceci :

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
    </configSections>
    <connectionStrings>
        <add 
            name="MonProgramme.Properties.Settings.MaBaseDeDonneesConnectionString"
            connectionString="Data Source=|DataDirectory|\MaBaseDeDonnees.sdf;Password='MonMotDePasse';Persist Security Info=True"
            providerName="Microsoft.SqlServerCe.Client.3.5" />
    </connectionStrings>
</configuration>

Et après application de la protection :

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
    </configSections>
    <connectionStrings configProtectionProvider="DataProtectionConfigurationProvider">
        <EncryptedData>
            <CipherData>
                <CipherValue>AQAAANCMnd8B...</CipherValue>
            </CipherData>
        </EncryptedData>
    </connectionStrings>
</configuration>

Vous trouverez ci-dessous le programme et son code source. J'ai simplement repris l'exemple fourni par Microsoft et j'ai ajouté un peu de code pour pouvoir passer le nom de l'exécutable en argument de la ligne de commande. Notez qu'il faut ajouter une référence à System.Configuration.

using System;
using System.Configuration;
using System.IO;
 
namespace EncryptCfg
{
  class Program
  {
    static void Main(string[] args)
    {
      if (args.GetLength(0) != 1)
      {
        Console.WriteLine(
          "Vous devez passer en argument le nom de l'exécutable à protéger."
        );
        Environment.Exit(-1);
      }
      if (!File.Exists(args[0]))
      {
        Console.WriteLine("Le fichier " + args[0] + " n'existe pas.");
        Environment.Exit(-2);
      }
      ToggleConfigEncryption(args[0]);
    }
 
    /// <summary>
    /// Bascule la protection de la section
    /// connectionStrings du fichier de configuration
    /// </summary>
    /// <param name="exeName">Nom de l'exécutable sans l'extension .config</param>
    static void ToggleConfigEncryption(string exeName)
    {
      try
      {
        // Open the configuration file and retrieve 
        // the connectionStrings section.
        Configuration config = ConfigurationManager.OpenExeConfiguration(exeName);
 
        ConnectionStringsSection section = config.GetSection("connectionStrings") 
          as ConnectionStringsSection;
 
        if (section.SectionInformation.IsProtected)
        {
          // Remove encryption.
          section.SectionInformation.UnprotectSection();
        }
        else
        {
          // Encrypt the section.
          section.SectionInformation.ProtectSection(
            "DataProtectionConfigurationProvider"
          );
        }
        // Save the current configuration.
        config.Save();
 
        Console.WriteLine(
          exeName + " : Protected={0}", 
          section.SectionInformation.IsProtected
        );
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
      }
    }
  }
}
AttachmentSize
File EncryptCfg.exe5.5 KB

Add new comment