Introduction
Encrypting the connection string for Windows applications can be easily done in a few simple steps explained in this article.
Background
Wanting to secure connection strings for Windows applications, I read in the
.NET Framework Developer's Guide which explains that "ASP.NET 2.0 provides a new feature, called
'protected configuration', that enables you to encrypt sensitive information
in a configuration file. Although primarily designed for ASP.NET, protected configuration
can also be used to encrypt configuration file sections in Windows applications."
Using this guideline, I was able to encrypt and decrypt my connection strings
in my application on my computer, but upon distributing the application, the following
error occurred: "Failed to decrypt using provider 'MyUserDataProtectionConfigurationProvider'.
Error message from the provider: Key not valid for use in specified state. (Exception
from HRESULT: 0x8009000B)", as described in "How
To: Encrypt Configuration Sections in ASP.NET 2.0 Using DPAPI".
This error occurs because the key used to decrypt the string is machine specific
by default.
To get around this problem, Hameer Saleem wrote an excellent article, "Implementing
Protected Configuration With Windows Apps," explaining how to
encrypt application settings on distributed applications through the Windows installer.
Being based on Hameer Saleem's article, this article is very similar to it, but
leaves out a step or two and focuses on connection strings.
Using the Code
- Store connection
string in the Application
Settings
- Add an installer class and
override the install method
- Add a Setup Project with a custom action containing the project's primary output
- Install the application
1. Store connection string in the Application Settings
Create a new
project and in the
Settings page of the
Project Designer, create a new
Application Setting for the
connection string. In this example, the project is called "MyConnectionString"
and the connection string
Application Setting is called "ConnectionString".
How to: Create
Application Settings Using the Designer
By creating a new Application
Setting, the
Project Designer will create a settings class which exposes the connection string to the project through the Properties namespace,
making it easy to access the connection string from code. Application settings are
accessed using the Properties.Settings.Default
object, as shown below:
string databaseConnectionString = Properties.Settings.Default.ConnectionString;
For detailed information, see "Using Settings in C#"
The Project
Designer will also create an
application configuration file, called app.exe.config (where app
is the name of your main executable file), which will contain the
Application Setting of the
connection string:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<connectionStrings>
<add name="MyConnectionString.Properties.Settings.ConnectionString"
connectionString="Data Source=(local)\SQLExpress;Initial
Catalog=AdventureWorks;Integrated Security=True" />
</connectionStrings>
</configuration>
2. Add an installer class and override the install method
To protect the connection
string, add the System.Configuration reference, add an
Installer Class to the project and then override the
Install Method in that class with the following code:
using System.Configuration;
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
Configuration config = ConfigurationManager.OpenExeConfiguration(
Context.Parameters["assemblypath"]);
ConfigurationSection section = config.GetSection("connectionStrings");
if (!section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection(
"DataProtectionConfigurationProvider");
config.Save();
}
}
How to: Add
New Project Items
With the System.Configuration.ConfigurationSection, one can get an application settings
section from the application configuration file and encrypt it using the Window
Data Protection API or the RSA encryption algorithm. In this example, I'm
getting the "connectionStrings" section of the application
configuration file and encrypting it using the
Window Data Protection API.
For more information, see
Securing Connection Strings
3. Add a Setup Project with a custom action containing the project's primary output
Then, one needs to add a
Setup project to one's solution which contains the project's primary output | |
Select the Custom
Actions Editor and add a
Custom Action
Then select the primary output for your application. In this case, it's the
primary output for MyConnectionString | |
4. Install the application
That's it. Now, when the application is compiled and installed, the application
configuration file will be protected to look like this:
="1.0"="utf-8"
<configuration>
<configSections>
</configSections>
<connectionStrings configProtectionProvider=
"DataProtectionConfigurationProvider">
<EncryptedData>
<CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA4UsuQ1ImfEC
1YDl6Y5urvwQAAAACAAAAAAADZgAAqAAAABAAAACtumZfWRxJZ76othC3F0a
UAAAAAASAAACgAAAAEAAAAOE/Mbi8KBK6v9mA0CaH6m/AAQAA7HWRf5RjQ5q
jknQ+wjFQtIyrXQ7N3Pqtc9f6WiJXU8hmOKo2lC4fW/y+7ttDpx4Wse/
Ez7b2vzu7B4KcEF1rr+ic/nMZRcHUsvG6E/DVEIaWOvSe0IcVOdqj
UD6iBySwHdrY2QT50HuHI/MGR60vP84V+VwQd0IPmMp5kBOFawgCfTCq
61ZJebZ9+Ng4AVZ4jpAgNTp7DVZXz3IVpoLPHPnwbvkbvAI/HCX2MYlGj
hTzGyzSViTvPCMeMvvaz5Jdfj2Z3JeRcVQSgh3xjl8amcR0M25eCHXKyc
f6YLUXFRs4LgYTaYqIoRDya1WpAgbv0pQ5mZAa1SqUQ5AvCyuPR+1XT9m
DZTlhJALdnIJWxRiRJ38kzRJvenGjPrvKAZCISSHYC0olZha34ijQ/RgMW
96kmWRw0Kr2kiZEeUdhUWCQ6Qaa3EwKjF3b9u0WrHw1UdE6ZRL62W6p6PkE
+GmGoX1s3f73U7LPHXdKXsWapdTpSk51pTxGDmuQswHiDpiWeEeI1gO3pmw
an4rpSjlAhjxi/OIu7Bm98VOa8SvmP1oTCXN9XefZWekZ86z7+7DLFLV2H6/
KTK9LqHAew8whpRQAAAD3As0X5IF2d18
SdVKCYWyO+o/l3A==</CipherValue>
<;CipherValue>;AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA4U... <;/CipherValue>;
</CipherData>
</EncryptedData>
</connectionStrings>
</configuration>
When run, the program will decrypt the protected data and return
the correct string
Console.WriteLine(Properties.Settings.Default.ConnectionString);