How To Use Symmetric Key To Encrypt Connection String in Web.config file And What the Code for doing that (with libraries)
use System.Configuration.RsaProtectedConfigurationProvide
Encrype your connection string with simple application. and then add it to your main application. this will use machine key. it will work only with one server, where you have created thsi encryped connection string.
Protecting Connection Strings and Other Configuration Information
Related
I have working code that will encrypt and decrypt a string provided to methods and this all works fine for when im storing a users entered password for convenience later.
However what I am trying to do is provide a password (encrypted) in the applications config file that allows users to pull data from an SQL server on the same domain.
Because I've used ProtectedData.Protect with DataProtectionScope.CurrentUser it has been encrypted using me as a key meaning users cannot decrypt this key, and DataProtectionScope.LocalMachine is also not applicable.
private static byte[] Entropy = { // Some arbitrary numbers };
public static string Encrypt(string _toEncrypt)
{
byte[] originalText = Encoding.Unicode.GetBytes(_toEncrypt);
byte[] EncryptedText = ProtectedData.Protect(originalText, Entropy, DataProtectionScope.CurrentUser);
return Convert.ToBase64String(EncryptedText);
}
public static string Decrypt(string _toDecrypt)
{
byte[] EncryptedText = Convert.FromBase64String(_toDecrypt);
byte[] OriginalText = ProtectedData.Unprotect(EncryptedText, Entropy, DataProtectionScope.CurrentUser);
return Encoding.Unicode.GetString(OriginalText);
}
Is there another way of doing this that allows for a password to be decrypted when required and be provided in its encrypted format for security reasons?
Since you're using app.config for your configuration file, you can actually use the aspnet_regiis utility to encrypt sections of the file.
It's been a while since I've had to do this, but there are some resources on the internet if you do some searching (for example). But, if I recall correctly the steps are basically:
Temporarily rename your app.config to web.config because
aspnet_regiis will only work on web.config.
Open a Developer Command Prompt (might need to do it as an administrator).
Run aspnet_regiis -pef <the section you're encrypting> <path to your web.config>. The path should just be the folder where the configuration file can be found, don't include web.config.
Rename your configuration file back to app.config.
This will need to be run on the server or machine hosting your application. If your application is not running from a single server things become more complicated as you will have to export the key, and import it to every computer running the application. This article contains the steps:
Create a machine-level RSA Key Container (1 time step)
Exporting the Custom RSA Encryption Key (1 time step)
Importing the Certificate (1 time step - per machine)
Adding Permissions to the Certificate (1 time step - per machine)
Encrypting the Configuration Section
Decrypting the Configuration Section
You don't actually need to do any sort of special decryption in your application. The configuration system will handle that for you automatically.
If I want to make a C# login form, with a Mysql databse which provides the userdata, in c#, i would say it's unsafe to write the database password, database username and database name in the connection string. Am i right? And is there another way like a webserver which will connect to the database and check if userdata is right?
You should store such things in a configuration file. .NET has the option to use encryption in web.config / app.config.
https://msdn.microsoft.com/en-us/library/ms254494(v=vs.110).aspx#Anchor_2
Either way you will have to provide those credentials. You can pass them in connection string in your code (OR) can have those maintained in web.config or app.config file in which case you can actually encrypt the password and have the encrypted value mentioned in connection string.
I have the following connection string:
Data Source=Paul-HP\MYDB;Initial Catalog=MyMSDBSQL;Persist Security Info=True;User ID=sa;Password=password
(.net webservice)
This can obviously be viewed simply by opening up the app.config file and looking at the configuration settings.
What I need is a way to make a hacker unable to see the password. But at the same time, leave it customisable so that it can be changed when deployed on another database.
You have a number of options - the ones that I am aware of (in order of preference):
Use integrated (SSPI) security where you don't need to include a password in the config file
Encrypt the connection string (see Encrypting Configuration Information Using Protected Configuration)
Store the username and password separately and use string formatting to construct the full connection string,
So for example the connection string might look like this:
Data Source=Paul-HP\MYDB;Initial Catalog=MyMSDBSQL;Persist Security Info=True;User ID={0};Password={1}
I'd go for option 1, if thats not possible then option 2. I've mentioned option 3 for completeness.
Have you read Protecting Connection Information (ADO.NET)?
First of all, don't use the "SA" account. It leaves your database wide open if someone gets the password. Use a custom account which only is allowed to do CRUD operations on a specific database.
The only way to get web.config is to hack your server. And if they have done that, you're screwed anyway.
Probably easiest to encrypt the connection strings within the web.config or app.config
See How To: Encrypt Configuration Sections in ASP.NET 2.0 Using DPAPI
I Suggest en/decrypting the connection string. Therefore the connection string has to be set manually.
For encryption take a look at:
http://dotnet-snippets.de/dns/encrypt-and-decrypt-strings-SID205.aspx
For Custom Settings take a look at:
http://msdn.microsoft.com/en-us/library/8eyb2ct1.aspx
Replace the Encrypted with the correct one at runtime:
public static void SetAppSettingValue(string Key, string Value)
{
System.Configuration.Configuration config == ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Add an Application Setting.
config.AppSettings.Settings[Key].Value = Value;
// Save the changes in App.config file.
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
}
You could encrypt the connection string - then when you access the connection string, decrypt it. This isn't fool proof though as you're then stuck with the problem of where to store the key to decrypt the connection string!
I want to encrypt the password in connection string. When I make a connection to DB the connection string is openly stored in App.config and I need to find a way to keep only password encrypted.
Lets say this is your connection string:
<connectionStrings>
<add name="cs" connectionString="Data Source=myServerAddress;Initial Catalog=myDataBase;User Id=myUsername;Password=XXSDFASFDKSFJDKLJFDWERIODFSDFHSDJHKJNFJKSD;"/>
</connectionStrings>
Then you can do something like this:
string myCs = System.Configuration.ConfigurationManager.ConnectionStrings["cs"].ConnectionString;
System.Data.SqlClient.SqlConnectionStringBuilder csb = new System.Data.SqlClient.SqlConnectionStringBuilder(myCs);
csb.Password = EncDecHelper.Decrypt(csb.Password);
myCs = csb.ToString();
You can write EncDecHelper.Decrypt by using samples from here: Encrypt and decrypt a string
Use the connectionStrings configuration section and encrypt the whole section - instead of just the password.
This is safer as your app config will no longer have the server names and user names in plain text either.
There are how-to documents for encrypting configuration sections on MSDN for RSA or DPAPI.
Maybe decrypt connection string from your config before application was loaded.
As an addition to the other answers, isn't it better to use the file in Source Control as a template, with just dev/test encrypted connection strings so that it works in dev/test.
For production (or other environments the app is deployed to), the encrypted credentials file is generated separately to the specified template format, managed/updated/deployed separately, has appropriate security permissions applied, never seen by anyone other than DBA/DevOps.
I used the following command to encrypt my connection string but an error ocurred
"The connection name
'DatabaseConnectionString1' was not
found in the applications
configuration or the connection string
is empty"
How can I encrypt it while keeping the application working?
The command used was
aspnet_regiis -pef "connectionStrings" "C:\Users\ANAS\Documents\Visual Studio 2008\WebSites\WebSite7"
What if I move the encrypted application to another computer? Will it work?
How can I encrypt it while keeping the
application working?
You can't. If you change your web.config your application is initialized.
What if I move the encrypted
application to another computer? Will
it work?
It will not work. You can only encrypt config sections on the same machine you decrypted it before. That's the reason why this is secure: You can't take a config file away and decrypt it on another machine.