2

I'm working on my first real WinForms application, and my boss has asked that I figure out a way to encrypt the connection string inside the app.config. I've read some of the suggestions in other questions about connection string encryption, and I recognize that it isn't a silver bullet answer to the security/privacy problem. We've considered writing web services to retrieve data from the database, but this is a very small project and unfortunately isn't a priority at this time.

Edit: I left out the detail that I'm working for a state institution (community college) where, because we're identifying students using a state-mandated private system ID, we need to secure the application in some form or fashion. Students may enter their network IDs to identify themselves (which we need to protect anyway as some students have restraining orders and need much of their records kept private), but many students only know their system IDs (which are always kept private).

Regardless, we'd like to get this process working in conjunction with ClickOnce deployment, but my encryption process crashes the application when I run the ClickOnce executable. Here's my encryption code (which is lifted from another question here on SO):

public static void EncryptConfigSection(string sectionName)
{
    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

    ConfigurationSection section = config.GetSection(sectionName);

    if (section != null)
    {
        if (section.IsReadOnly() == false &&
            section.SectionInformation.IsProtected == false)
        {
            section.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");

            section.SectionInformation.ForceSave = true;

            config.Save(ConfigurationSaveMode.Full);
        }
    }

    ConfigurationManager.RefreshSection(sectionName);
}

I'm calling this function from the Main() function in Program.cs, but I'm not sure if this is the appropriate place for it. Additionally, while this function encrypts the app.config correctly, as soon as I exit the application, the app.config decrypts. I feel like I'm missing a piece to the puzzle (or perhaps large swaths of the puzzle).

Can anyone offer me some insight into these problems? I'd like to reiterate that I recognize that web services are the end goal here, so if this is just not a solvable problem using CLickOnce, then I'm willing to suggest that we prioritize writing web services now.

jwheron
  • 2,553
  • 2
  • 30
  • 40
  • So you're using credentials that have enough rights to do something that would require you to encrypt its details? – Austin Salonen Sep 27 '11 at 15:03
  • Yes -- a detail I left out above (and which I will rectify after finishing this comment) is that I work for a community college, and this application allows students to log in to tutoring centers using either a potentially-sensitive user ID (we have students with restraining orders) or an always-hidden system ID (state law mandates that we not identify students publicly using the system ID), so since we're granting access to the system IDs -- however limited -- we need to secure the connection somehow. – jwheron Sep 27 '11 at 15:11
  • @Downvoter, what's wrong with this question? – jwheron Nov 29 '11 at 15:32

1 Answers1

1

Have you looked at this topic? It talks about setting up the client using DPAPI so the string is encrypted. I would still look at the web services route rather than embed a connection string, encrypted or not, into a client application. This is ESPECIALLY true if you are talking about client apps outside of your domain (ie, non-employee use).

Community
  • 1
  • 1
Gregory A Beamer
  • 16,870
  • 3
  • 25
  • 32
  • I did read that, but it was unclear to me whether or not I could encrypt the entire app.config and then decrypt individual sections as I needed them. – jwheron Sep 27 '11 at 15:09
  • When you deploy an application, whether through an installer or ClickOnce, and you want to use DPAPI, you end up encrypting when the application is "installed". it is a bit more of a pain in ClickOnce, but it is solvable. The issue, however, is still one of what is the best security. And, having the actual database strings behind your firewall (the web service solution) is more secure than encrypted on the user's box. In addition, the services can be used for other purposes (applications?). DISCLAIMER: Most of my work is architecting external API solutions, so I may be biased. – Gregory A Beamer Sep 27 '11 at 15:14
  • We aren't deploying the application to a wide audience, thankfully, as it'll be installed only on computers in tutoring centers on campus (no more than 25 or so machines), but I do agree that the web services solution is the better idea. I'll push for that while I try to get the DPAPI stuff working. Thanks for the insight. – jwheron Sep 27 '11 at 15:22
  • If you have full control of the deployed solution, you might also look into pre-encrypting, with keys (setting the keys in the config) and pushing it out. Since ClickOnce pulls from a compiled set of classes, the pre-encrypted config should be fine. You will either have to manually do this or set it up as a post-compile step, but it can be done. If you go this route, automate it, however, as you don't want someone to miss the post step and leave the connection open. Open connection strings are also possible if you restrict the user to specific objects, but not my first choice. ;-) – Gregory A Beamer Sep 27 '11 at 15:36
  • I didn't end up using the ProtectedData class, but I did get this working using DPAPI encryption instead of RSA. I'm still not sure why RSA encryption would crash the application after it's deployed, but there you have it. – jwheron Sep 29 '11 at 16:22