Encrypt connection string in app.config
Asked Answered
G

7

54

I am having trouble encrypting a connection string in app.config. I have code that will protect the connectionStrings section of app.config, but the password is still displayed in plain text.

I need to encrypt the connection string in so it is not in plain text when deployed. I see similiar questions on SO for web.config, but not app.config.

Gildea answered 24/7, 2012 at 18:47 Comment(2)
Keep in mind that if you use ProtectSection() and encrypt your connectionstring, I simply can copy your encrypted .config file, use it with my application and call UnprotectSection(). This will give me back your original connectionstring in plain text.Swan
@RunCMD, as long as it is on the same computer, then yes. According to Microsoft docs, "The connection string can only be decrypted on the computer on which it was encrypted."... ref: learn.microsoft.com/en-us/dotnet/framework/data/adonet/…Absorbefacient
P
25

Have a look at This Article it has some very useful examples. You're basically looking for System.Configuration.SectionInformation.ProtectSection to help you out here.

Also have a peek at Implementing Protected Configuration

Polysyndeton answered 24/7, 2012 at 18:52 Comment(2)
Is this method usable with DataSets and TableAdapters inside of them ? They Select the ConnectingStrings stored in your app.config .. if its Encrypted will it still be automatically Decrypted ??Atlante
This is basically a link-only answer. Would you mind adding the essentials of the links to your answer to keep the answer useful if the links break?Alper
M
66

You can easily apply the same solution as the web.config you just have to rename your app.config to web.config, encrypt with the aspnet_regiis tool and then rename it back to app.config.

  1. Rename app.config to web.config
  2. Open command prompt and type:
    %windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pef "connectionStrings" c:\<folder containing your web.config> (stop at folder level and don't put the trailing "")
  3. rename web.config back to app.config

You can open it in notepad to see the encrypted file. In visual studio you will see it's decrypted. You can use your connection string the same way as if it was not encrypted. (Note that it can only be decrypted on the same machine it's encrypted on.)

Matthewmatthews answered 21/3, 2015 at 0:11 Comment(13)
Perfect! right to the point! and for decrypt: %windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pdf "connectionStrings" c:\folderMelodic
This worked for me and is a lot easier to implement than the accepted answer.Cercaria
For me, I had to run the command prompt as admin to get this to work.Grimaud
I used the method to change the string it is encrypted, but after populating app.config file back in my VS 2012, it is showing error: "the element ConnectionString has invalid child element EncryptedData in namespace w3.org/2001/04/xmlenc#Element". Helpless!Vines
This will work only on the same computer used to encrypt the file; if you deploy to another computer it wont work, from microsoft noteChoe
This answer will only encrypt the app.config, but be warned your computer may not read your connection stringsEssa
@Essa I'm facing the same issue, Did you solve this ?Deenadeenya
@AbdulsalamElsharif Yes, I used Dpapi encryption instead of aspnet_regiis.Essa
@Essa Can you help me to used it and I'll be thankfulDeenadeenya
@AbdulsalamElsharif here is the link codeproject.com/Articles/18209/… do take note this is Windows form, VB.net, not C#Essa
@Essa Thanks for you help, I realy appreciate it.Deenadeenya
Is there any reason that Framework v2.0.5... is being reference over a later framework version to use aspnet_regiis? Seeing how this answer and comments were posted when later versions of .Net are available.Cormac
I had to put in quotation marks - "C:\Folder"Confidante
P
25

Have a look at This Article it has some very useful examples. You're basically looking for System.Configuration.SectionInformation.ProtectSection to help you out here.

Also have a peek at Implementing Protected Configuration

Polysyndeton answered 24/7, 2012 at 18:52 Comment(2)
Is this method usable with DataSets and TableAdapters inside of them ? They Select the ConnectingStrings stored in your app.config .. if its Encrypted will it still be automatically Decrypted ??Atlante
This is basically a link-only answer. Would you mind adding the essentials of the links to your answer to keep the answer useful if the links break?Alper
A
6

• Rename App.config file to web.config<br> • Run Command prompt as admin:

For encrypt:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -pef "connectionStrings" your project location within quotes and -prov "DataProtectionConfigurationProvider"

Ex:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -pef "connectionStrings" "D:\location\location1\location" -prov "DataProtectionConfigurationProvider" 

For Decrypt:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -pdf "connectionStrings" your project location within quotes.

Ex:

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

For error:

Add this in Configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"

Like this:

enter image description here

• Finally, Rename web.config to App.Config

Aleciaaleck answered 11/10, 2018 at 13:39 Comment(0)
U
4

Additionally, If there is anyone who wants to encrypt and decrypt connection strings in web farms here are the steps:

  1. Create an RSA key: aspnet_regiis -pc "MyKeys" -exp

  2. Grant access for application pool identity to this key: aspnet_regiis -pa "MyKeys" "IIS AppPool\ApplicationPoolName" -full

  3. Add RSA provider to the web.config:

    <configuration>
        <configProtectedData>
            <providers>
                <add name="MyProvider" 
                     type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" 
                     keyContainerName="MyKeys" 
                     useMachineContainer="true" />
            </providers>
        </configProtectedData>
    </configuration>
    
  4. Encrypt web.config by using the RSA provider: aspnet_regiis -pe "connectionStrings" -app "/MyApplication" -prov "MyProvider" Note: You can use the alternative syntax like the one we did for a single server scenario. Example: ASPNET_REGIIS -pef "connectionStrings" "D:\inetpub\wwwroot\applicationFolder" -prov "MyProvider"

  5. Open the web.config and confirm that the connection string is encrypted

  6. Test the site and confirm that it is working

  7. Try decrypting the web.config. Create a test.aspx file with the code below inside. Browse it to see the decrypted file

  8. Export the RSA key to the C drive: aspnet_regiis -px "MyKeys" "c:\keys.xml" -pri

  9. Copy this file to the second server in the web farm

  10. Import it in that server: aspnet_regiis -pi "MyKeys" "c:\keys.xml"

  11. Grant access to this key (same as Step 2)

  12. Test the application in the second server

Source: How to encrypt and decrypt connection strings

Urial answered 26/7, 2019 at 20:23 Comment(0)
B
3

Define the location of config File

Configuration config  = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

if you want to encrypt connectionStrings

config.ConnectionStrings.SectionInformation.ProtectSection(Nothing);

you must be aware of app config portions

so if you want to encrypt AppSettings

config.AppSettings.SectionInformation.ProtectSection(Nothing);

enter image description here

Byng answered 11/12, 2016 at 5:30 Comment(2)
This works, but in my case I had to replace "Nothing" to "DataProtectionConfigurationProvider"Ruthenium
@Salen-Ahmed you forgot to save configuration. config.save()Inevasible
L
2

A way to automate this:

ProjectSettings > Compile > BuildEvents > Edit Post-build

Paste the code below:

SET ApplicationName=YourAppWithoutExtention
echo.
echo POST BUILD ACTIONS
echo ====================

if EXIST web.config (
    echo Deleting web.config
    DEL web.config
)

echo Renaming %ApplicationName%.exe.config to web.config
REN %ApplicationName%.exe.config web.config

echo Running aspnet_regis against webconfig
SET rpath=%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pef "connectionStrings" "$(TargetDir)
SET rpath=%rpath:~0,-1%"
echo Path: %rpath%
%rpath%

echo Renaming web.config to %ApplicationName%.exe.config 
REN web.config %ApplicationName%.exe.config

echo Done.

Replacing "YourAppWithoutExtention" with your app name.

Then every time it builds, it will automatically encrypt your app.config.

Leifeste answered 6/1, 2019 at 13:41 Comment(1)
How about publish?Neoprene
R
0

After hours of researching solutions related to the question.

I found a reasonable solution:

The problem with your approach is that your app will need to contain both a decryption key and a decryption algorithm in order to decrypt and use the connection string.

It would be dangerous to assume that even a junior developer won't be able to just debug the code, step through the decryption and get the unencrypted string at the end.

Storing secrets (like connection strings, passwords, API keys) in config files is strongly discouraged as it's a very insecure practice. Instead you should be using a "secrets manager" service -- it's a secure online service that can store your passwords and lets you retrieve them when needed.

When using a secret management service, no secrets or decryption key or algorithm is stored in your source code. Retrieving a secret is as simple as this:

For Azure Key Vault:

 var keyVaultUrl = "https://<your-key-vault-name>.vault.azure.net/";
 var credential =  new DefaultAzureCredential();    
 var client = new SecretClient(vaultUri: new Uri(keyVaultUrl), credential);    
 KeyVaultSecret secret = client.GetSecret("<your-secret-name>");    
 Console.WriteLine($"{secret.Name}: {secret.Value}");

For AWS Secrets Manager (skipped some error handling code):

 var client = new AmazonSecretsManagerClient(accessKeyId, secretAccessKey, 
                                             RegionEndpoint.APSoutheast2);
 var request = new GetSecretValueRequest {
     SecretId = secretName
 };
 GetSecretValueResponse response = null;
 response = client.GetSecretValueAsync(request).Result;

You can also search for an alternative secret manager and implementation like Google Cloud Secret Manager or others.

This approach has lots of advantages over the storage of secrets locally:

  • you don't have to mess with storing different values in configs for Prod/Staging/Dev environments -- just read appropriately named secrets (such as '[Dev|Prod|Stag]DBPassword`

  • only selected few people can have access to the very important secrets (such as, I dunno, say an authorisation code to transfer all $$$ from Deus account to E-Coin wallets around the world #revolution), and their access can be revoked at any time

  • if anyone steals your source code (disgruntled employee, accidental leak) none of your passwords have been leaked

  • changing a password is easy -- you just update it using the could management console and restart the app(s)

How to use AWS Secrets Manager to store & read passwords in .Net Core apps

How to securely store and retrieve sensitive info in .NET Core apps with Azure Key Vault

Credits and thanks to @smartial-arts Reference; the second answer.

Rogers answered 10/5, 2022 at 19:35 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.