27

I have an app.config file that I need to distribute with my application. It was created because of a Service Reference to an ASMX web service I added.

It isn't a huge deal if this file is modified/viewed, but I still would like to make it secure. I already check the hash of the config and make sure it is valid, but I still want an added layer of protection.

Here is my config: http://pastie.org/private/zjdzadnfwrjvwkmlbdsqw

So is there anything in there that I can encrypt or anything?

Eaton
  • 1,310
  • 2
  • 15
  • 31
  • http://stackoverflow.com/questions/855483/wcf-encryption-solution-for-app-config-viewable-to-a-client might help – PRR Jul 28 '10 at 08:30

6 Answers6

50

You cannot encrypt the entire <system.serviceModel> - it's a configuration section group, which contains configuration sections.

The aspnet_regiis will only encrypt configuration sections - so you need to selectively encrypt those parts you need, like this:

cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
aspnet_regiis.exe -pef "system.serviceModel/bindings" .
aspnet_regiis.exe -pef "system.serviceModel/services" .

etc.

With this, you can encrypt what you need easily - what isn't too important, can be left in clear text.

Word of warning: since it's aspnet_regiis, it expects to be dealing with a web.config file - copy your app.config to a location and call it web.config, encrypt your sections, and copy those encrypted sections back into your own app.config.

Or write your own config section encrypter/decrypter - it's really just a few lines of code! Or use mine - I wrote a small ConfigSectionCrypt utility, come grab it off my OneDrive - with full source (C# - .NET 3.5 - Visual Studio 2008). It allows you to encrypt and decrypt sections from any config file - just specify the file name on the command line.

Michael Blackburn
  • 3,161
  • 1
  • 25
  • 18
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 1
    Excellent! Just the answer I was seeking. Your command line app did the job and I will tuck it away for future use. Thanks for the help! – Eaton Jul 28 '10 at 14:24
  • The skydrive link seems to be down. Any other way we can get the command line utility? – M.R. May 07 '14 at 20:39
  • @M.R.: sorry 'bout that - updated the link to point to the "new" OneDrive location – marc_s May 07 '14 at 20:45
  • The OneDrive file is reported as Malicious by Chrome and blocked. – Jay Greene Aug 25 '14 at 20:09
  • The OneDrive file is no longer available – Jack Jul 20 '16 at 01:46
  • Hey @marc_s, are you available to put your `ConfigSectionCrypt` to somewhere else since this OneDrive link is broken. Thank you. – Soner Gönül Nov 02 '16 at 11:14
  • @SonerGönül: I recreated the link and posted it here - does this one work for you? – marc_s Nov 02 '16 at 13:38
  • Thanks. But, I don't see how this is secure. Anyone who gets the encrypted config file can just run it through .NET to decrypt it. Or am I wrong? Is there a better way? – N73k Jan 30 '20 at 17:55
  • @N73k the file is encrypted with a key stored on the machine. That file can only be decrypted on the machine on which it was encrypted. This makes it a little challenging, since you have to decrypt the file before moving it to another machine. – Michael Blackburn Apr 23 '20 at 20:16
5

You must set a reference to System.Configuration.dll in your project for the code to run.

ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
                configFileMap.ExeConfigFilename = exeConfigName;
                System.Configuration.Configuration myConfig = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);

                ConnectionStringsSection section = myConfig.GetSection("connectionStrings") as ConnectionStringsSection;

                if (section.SectionInformation.IsProtected)
                {
                    // Remove encryption.
                    section.SectionInformation.UnprotectSection();
                }
                else
                {
                    // Encrypt the section.
                    section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
                }

                myConfig.Save();
Arul
  • 71
  • 1
  • 1
3

I use the following to encrypt my connection strings in web.config, why not use the same for yourself. I am not sure though.

To Encrypt:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -pef "connectionStrings" "\myWebSitePath"

To Decrypt:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -pdf "connectionStrings" "\myWebsitePath" 

Put them in bat files so you can encrypt or decrypt on the fly.

loxxy
  • 12,990
  • 2
  • 25
  • 56
  • 1
    They aren't connection strings, so that wouldn't work for this. – Eaton Jul 28 '10 at 03:11
  • @Eaton, you can use this to encrypt any section of the config file. The connectionStrings section is just the most common location of "secrets" – Michael Blackburn Apr 23 '20 at 20:17
  • Hi Michael, advice is no longer needed on this 10 year old question, thank you though! – Eaton Apr 23 '20 at 21:14
  • 1
    @loxxy but anyone basically could google it, come to this post and enter this decrypt command and read it again? (same way someone ecrypted it before) ? – Roxy'Pro Jun 06 '20 at 14:43
3

The answer from @marc_s is awesome, but I had a little trouble understanding exactly how to do what he had mentioned. This MSDN forum answer does a really good job of explaining the same process in simpleton format for people like myself who are not programming big shots yet. Here is the breakdown:

The best way to do this is to protect it using the aspnet_regiis.exe application. Even if the application is not an ASP.NET application, this will still work. Here's how.

  1. Rename the app.config in your directory to web.config (don't worry, this is just temporary, we'll rename it back later).
  2. Go to the command prompt.
  3. Type the following (replace the last argument with the path containing the directory to the app.config, currently renamed to web.config. For example, if the full path to the web config is "C:\documents and settings\bob\projects\myproject\web.config", you would use "C:\documents and settings\bob\projects\myproject")

%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pef "connectionStrings"

  1. You should see it say "Succeeded!"
  2. Reopen the web.config, it should look something like this:
<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider">

    <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"

      xmlns="http://www.w3.org/2001/04/xmlenc#">

      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />

      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">

        <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">

          <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />

          <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">

            <KeyName>Rsa Key</KeyName>

          </KeyInfo>

          <CipherData>

            <CipherValue>rUmEA8h02uMZ5M4uEVtL+5M/UvPuyJ4UJz5d/Pd4h4jpFPGVf29ha4d+BMt/iOupVisXDxuZY1jzyc6O0ZixGcCkZqbynwKjouVANQVWUnDgIFgVap2ohsxjblAMtWHTUWDlL0ST5tqSVHNQE+r9G59Bnrp5HkuU3Eg09/8j6Jo=</CipherValue>

          </CipherData>

        </EncryptedKey>

      </KeyInfo>

      <CipherData>

        <CipherValue>U2JEHzJ+WjSdlocT00cC9TE3+Dn3v7xE1RwX7bKAPuISO2f3hm18MZHnm1hXEBlnDS6iBNRPN87+BJJvZXYz+Sis/ZD4xBZEP4jBG2F8tqlLUbagv3W4epbuTSp2aalb5rdcBoycdIzSj2CApOzSaSKkMDvZrX8yoJI9RfuGnOWmNa4bncHkUEDvWq+uCK/8uaQ48J5uRoq7O0YgIe9jDg==</CipherValue>

      </CipherData>

    </EncryptedData>

  </connectionStrings>

</configuration>
  1. Lastly, rename the file from web.config to app.config.

That's it! You shouldn't have to do anything else to get this to work. If you use the ConfigurationManager in your code to retrieve the setting, it should fetch it just fine for you using the same code.

That being said, if you're going to install this on several computers, you might want to consider providing user-specific logins to your server for each user who uses the application. That way you can still track what they do, and you can prevent them from logging on at all on a user-by-user basis.

MUlferts
  • 1,310
  • 2
  • 16
  • 30
2

Well the file will be read by the program when it is run so changing the file could be a bad idea, you could add checksums to each line to make sure it's valid by checking it in your application or checking for modifications since last run or something. I've never heard of encrypting an app.config before to be honest.

Jesus Ramos
  • 22,940
  • 10
  • 58
  • 88
  • I mainly would like to hide the URL to my licensing script in some way. I know that no desktop encryption method will completely restrict someone from viewing it, but I would like to hide it from the standard user. – Eaton Jul 28 '10 at 03:04
  • you can use some kind of ROT encryption and in your app you can decrypt it, ROT encryption is simply just character shifiting like using a standard shift like 2 a string that is "abc" becomes "cde" you can use much more complicated methods though but it's up to you on how much security you need. – Jesus Ramos Jul 28 '10 at 03:15
2

It isn't a huge deal if this file is modified/viewed...

In that case, what is the security for?

You can programmatically encrypt sections of a config file with SectionInformation.ProtectSection.

Andy West
  • 12,302
  • 4
  • 34
  • 52
  • Just to keep the URL out of sight from the standard user. – Eaton Jul 28 '10 at 03:09
  • I just don't want it to be plain text. – Eaton Jul 28 '10 at 03:10
  • SectionInformation.ProtectSection seems to be the easier solution, why go with the separate aspnet_regiis utility? – Cahit Mar 22 '11 at 01:37
  • SectionInformation.ProtectSection infers that you have an unencrypted source file prior to deployment, which is not secure. Aspnet_regiis.exe can be used to encrypt both on dev and prod versions, maintaining encryption on both ends at all times. It's unfortunate that aspnet_regiis.exe works on web.config but not app.config. – Dave Feb 08 '17 at 20:21