Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / database / SQL-Server

Encrypting windows application connection strings

3.65/5 (11 votes)
25 Apr 2007CPOL3 min read 1   6K  
This article shows a simply method of encrypting connection strings for windows applications

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

  1. Store connection string in the Application Settings
  2. Add an installer class and override the install method
  3. Add a Setup Project with a custom action containing the project's primary output
  4. 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

Screenshot - Settings.jpg

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:

C#
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:

C#
using System.Configuration;
public override void Install(IDictionary stateSaver) 
{ 
    base.Install(stateSaver);

    //Opens the specified client configuration file as a Configuration object 
    Configuration config = ConfigurationManager.OpenExeConfiguration( 
        //Gets the source directory of the installation from the default 
        //context parameters 
        Context.Parameters["assemblypath"]); 

    // Get the connectionStrings section. 
    ConfigurationSection section = config.GetSection("connectionStrings"); 

    //Ensures that the section is not already protected 
    if (!section.SectionInformation.IsProtected) 
    { 
        //Uses the Windows Data Protection API (DPAPI) to encrypt the 
        //configuration section using a machine-specific secret key 
        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 Screenshot - AddPrimaryOutput.jpg

Select the Custom Actions Editor and add a Custom Action

Screenshot - CustomActionsEditor.jpg Screenshot - AddCustomAction.jpg

Then select the primary output for your application. In this case, it's the primary output for MyConnectionString Screenshot - PrimaryOutput.jpg

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:

XML
<?xml version="1.0" encoding="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

C#
Console.WriteLine(Properties.Settings.Default.ConnectionString);

Screenshot - Output.jpg

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)