Windows Forms Connection String Encryption Challenges
Listed here are the issues and frustrations with the encryption/decryption of a simple connection string and the findings.
The scenario
Protect a connection string in the App.config file of a Windows Forms app by encrypting it. The app will use Enterprise Library 2.0 and an internal util library used in both Windows Forms and Web apps and deployed via ClickOnce. Simple enough? Right? Wrong!
Challenge #1 – Encrypting the connection string
The first thing I did was to encrypt directly the connection string. Although you have everything you need to encrypt/decrypt right in the .NET Framework, Microsoft didn’t made this operation simple for those who never touched encryption before. You quickly learn that some forms of encryption are tied to the machine where the encryption is taking place. Since I wanted to encrypt, on one machine and distribute the result to multiple clients, I had to select a non-random and non-machine specific method. A quick search lead me to the Obviex site where I found some well documented code:
http://www.obviex.com/samples/Encryption.aspx
I quickly incorporated a version of the above code and tested my app.
Challenge #2 – Enterprise Library 2.0
A quickly found out that Enterprise Library does not like connection strings that are encrypted. One solution would be to change Enterprise Library source code a little bit but that’s one thing I try to avoid for compatibility reasons. Back to square one.
Challenge #3 – Encrypting configuration sections
One cool new thing in the .NET Framework 2.0 is the ability to encrypt a whole section in the configuration file. However, I quickly found out two things:
- Almost all the info on the Web and on the documentation explain the process for Web apps
- The encryption is machine dependant
It’s very easy to encrypt a section in the configuration file, here’s the code:
public static void EncryptConfigSection(string sectionName)
{
Configuration config = ConfigurationManager.OpenExeConfiguration(onfigurationUserLevel.None);
ConfigurationSection section = config.GetSection(sectionName);
if (section != null)
{
if (!section.IsReadOnly())
{
section.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");
section.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);
}
}
ConfigurationManager.RefreshSection(sectionName);
}
What cool is that you don’t have to code anything special to read back the encrypted data. The Configuration Manager figures out that the stuff inside the section is encrypted and decrypts it automatically. Great, but this means that the config file must be deployed non encrypted. In a Windows Forms scenario, that’s bad. So what can you do?