21

I read and tested a lot to find the best practice to encrypt and deploy an app.config to different machines. In general, I would like to secure the content of the connection string from third parties and deploy the application to different machines. I will not configure each machine manually.

I know there are several ways like:

  • Aspnet_Regiis (RSAProtectedConfigurationProvider, DPAPIProtectedConfigurationProvider) bound to a machine, user or custom. RSA encryption key.

  • System.Security.Cryptography.ProtectedData bound to a machine or user.

  • Encrypt the app.config at the first execution. Which is not secure.

What do you recommend or what is the best practice to encrypt an app.config and provide the application to different machines by a setup or with copy&paste?

Andrei V
  • 7,306
  • 6
  • 44
  • 64
Andre Hofmeister
  • 3,185
  • 11
  • 51
  • 74

2 Answers2

12

Step 1 Create an RSA keypair

aspnet_regiis -pc yourkey -exp

Step2 Export you key in XML file

aspnet_regiis -px yourkey keyfile.xml -pri

for each machines

Step3 Import your container

aspnet_regiis -pi yourkey keyfile.xml (see step 2)

for each machines

Step4 Edit machine.config (canonical path C:\Windows\Microsoft.NET\Framework[64|32]\v[Version]\Config)

add in section configProtectedData this below element and set defaultProvider="YourProvider"

<add name="YourProvider"
                type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                description="Uses RsaCryptoServiceProvider to encrypt and decrypt for my infrastucture"

                keyContainerName="yourkey"

                cspProviderName=""
                useMachineContainer="true"
                useOAEP="false" />

Then you can encrypt in a machine and paste in other, remember that must give privileges to users with

aspnet_regiis -pa yourkey [DOMAIN\USER]

The administrators group is already authorized.

For more info http://msdn.microsoft.com/en-us/library/yxw286t2(v=vs.90).aspx

of course this steps you can put in a powershell/batch file

Another way for encrypt a connectionStrings section by code is

 var connectionStrings = ConfigurationManager.GetSection("connectionStrings") 
 if(!section.SectionInformation.IsProtected)
     connectionStrings.SectionInformation.ProtectSection("YourProvider");

In a connected and client/server scenario I propose you a solution that I have adopted in a wide network is of not distribute connection string in app.config but of require the connection's information at a service that can be an web service or a RESTful service after the user authentication.

In step more o less is thus

  1. Authenticate user
  2. Require connection info at service with username as parameter (HTTPS protocol)
  3. a service return connection string
  4. App it connect at DB

With this solution you can choose which server the user connects if you have regional server or more server

I hope be helpful

Community
  • 1
  • 1
Fabio
  • 1,890
  • 1
  • 15
  • 19
  • Does I use the same RSA keypair for each machine? Does every domain user which will execute the application needs privileges for the key? – Andre Hofmeister Oct 10 '14 at 16:23
  • Yes, you must use same key on all machines and give the privileges to the only the app pool user i.e. network service or applicatiopoolidentity of the app – Fabio Oct 10 '14 at 16:54
  • I think thats a fine solution for a server farm. But what if you would like to provide your application to more then 1000 machines and users? – Andre Hofmeister Oct 10 '14 at 18:39
  • is your scenario intranet or internet? For users authorization you can use a group, in addition all user in the administrators group are already authorized. – Fabio Oct 13 '14 at 06:48
  • Generally, I will need it for the intranet. The solution works fine, but I will wait a little bit more. Maybe there is a solution without configuring the client machine. However, thank you very much! I think you have to export the private key too in step 2. It works with `aspnet_regiis -px yourkey keyfile.xml -pri`. – Andre Hofmeister Oct 13 '14 at 09:29
  • Sorry my mistake, I update my post with another possible solution – Fabio Oct 13 '14 at 09:33
  • Hence, every user with privileges could decrypt the data, right? Thus a user could access the password in a connection string? – Andre Hofmeister Oct 13 '14 at 13:18
  • who has access the the RSA container can decrypt the connectionStrings. If you want to avoid this of decrypt operation in your app must impersonate a user authorized in (only) connection phase (i.e. administrator) see http://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity.aspx Of course if you use the impersonate strategy you can privileges only to a user, – Fabio Oct 13 '14 at 13:44
3

As I already mention in the question, there are many different ways to encrypt a configuration file. For a widely perspective I would like to describe an additional opportunity. I will not describe the concrete implementation, more the concept.

With a custom action in a msi installer you can encrypt the configuration file directly with the Windows Data Protection API (DPAPI). To secure the second entropy you can use an obfuscator. As a result, only the application is able to encrypt the configuration file.

Advantage

  • Quite secure.
  • No machine configuration is necessary.
  • Insert the credential during the setup.

Disadvantage

  • The configuration file is not encrypted in the setup. You have to protect it (permissions).

Please feel free to discuss and give some feedback to this answer.

Andre Hofmeister
  • 3,185
  • 11
  • 51
  • 74