Usar ficheros de configuración es algo muy común en el desarrollo de aplicaciones, tanto web como windows. En .net tenemos el fichero app.config (web.config) para
poder guardar información que puede cambiar en cualquier momento. Es muy típico almacenar en estos ficheros las cadenas de conexión que usará nuestra aplicación,
pero ¿qué pasa si en esta cadena de conexión va el nombre de usuario / contraseña, y no queremos que el usuario de la aplicación la conozca, abriendo este fichero?.
La solución es bastante simple, sólo tenemos que encriptar / desencriptar nuestro fichero de configuración. Este proceso puede parece muy complicado pero con .NET
es realmente fácil.
El framework de .NET pone a nuestra disposición el ProtectionProvider, con las implementaciones DataProtectionConfigurationProvider y RSAProtectedConfigurationProvider.
Encriptar un sección de nuestro fichero de configuración y guardarla es tan fácil como
[sourcecode language='csharp']
private void buttonEncrypt_Click(object sender, EventArgs e)
{
string provider = "DataProtectionConfigurationProvider";
//string provider = "RSAProtectedConfigurationProvider";
Configuration configuration = null;
ConnectionStringsSection section = null;
try
{
configuration = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);
if (configuration != null)
{
bool changed = false;
section = configuration.GetSection("connectionStrings") as ConnectionStringsSection;
if (section != null)
{
if ((!(section.ElementInformation.IsLocked)) && (!(section.SectionInformation.IsLocked)))
{
if (!(section.SectionInformation.IsProtected))
{
changed = true;
// Encrypt the section.
section.SectionInformation.ProtectSection(provider);
}
}
if (changed)
{
// Indicates whether the associated configuration section will be saved even if it has not been modified.
section.SectionInformation.ForceSave = true;
// Save the current configuration.
configuration.Save();
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
[/sourcecode]
Para desencriptarla tan sólo debemos hacer
[sourcecode language='csharp']
private void buttonDecrypt_Click(object sender, EventArgs e)
{
Configuration configuration = null;
ConnectionStringsSection section = null;
try
{
configuration = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);
if (configuration != null)
{
bool changed = false;
section = configuration.GetSection("connectionStrings") as ConnectionStringsSection;
if (section != null)
{
if ((!(section.ElementInformation.IsLocked)) && (!(section.SectionInformation.IsLocked)))
{
if (section.SectionInformation.IsProtected)
{
changed = true;
// Encrypt the section.
section.SectionInformation.UnprotectSection();
}
}
if (changed)
{
// Indicates whether the associated configuration section will be saved even if it has not been modified.
section.SectionInformation.ForceSave = true;
// Save the current configuration.
configuration.Save();
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
[/sourcecode]
Y la seccion <connectrionStrings> de nuestro fichero de configuración que originalmente era
[sourcecode language='xml'][/sourcecode]
pasará a
[sourcecode language='xml']; AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAXiiF4BJLPEqfjkx9sW5uUQQAAAACAAAAAAADZgAAqAAAABAAAADL7FyjP7ANaOQ1ecYsWnhBAAAAAASAAACgAAAAEAAAACEqOzhpnuUlwZ0o9CYqPduYAQAAFy/9mBUvK7zFTsqcIedI6Ay1O6Y5prCtuKmYMr5ObHD/9TMM+y6gO3wpq83qOQYpHiAs386svfRKr9nvdeHYUycJTeZq5V/c+iZvg47sW5rouqXO12Z+cUpYcxpuDaiN25xYbyNzZkwKjypEYEF3aqgS8wt0nhfepnVEoaGur7yxrXIc77xU/KTs7cSfjkSFMI4xvRzBr9sgKQikpeoFsohBuP5fqOLKSYNMxlszuy50KblfzqE9Jj2a6PhLpVWOGdLwvofnTAYpNMNhxyhfNKv/oLg2+IWahuOwaStnVE32cEFlaxKdQ18VwZv2A/UWoKJw1XRHGsPmVPG7ToOZZC9/+Al2amJfXYp8GFQIOgNF8T1crkQvm5TC9lO7JloDxXqjKIROs140CmuYPQXTcBFoghAgXzkNEK3BNGOGSe0twjdkt511zeOkYf2a3/NpA/hTed25ffaVBvxtCNWwHw64oNwhDOcA3JtCL7QFCqLqUPFndoCEYHAAEsxc3LaVZrfD2ymTvPitceZxceKH0mtf0SgECrTHFAAAAONP+7+I5+McJmln/tAYJoiVKsv2 [/sourcecode]
Hay que tener en cuenta que hay determinadas secciones que no se pueden encriptar como son
- <processModel>
- <runtime>
- <mscorlib>
- <startup>
- <system.runtime.remoting>
- <configProtectedData>
- <satelliteassemblies>
- <cryptographySettings>
- <cryptoNameMapping>
- <cryptoClasses>
También hay que recordar que el proceso de encriptar y desencriptar el fichero de configuración puede afectar al rendimiento de nuestra aplicación.
