I have try to encrypt with code below, but it can use only on my PC, other PC can't connect to SQL server in my PC. anyone help me? thanks so much!!!
(I also try with aspnet_regiis.exe but have same problem)
public static void ProtectSection(String sSectionName)
{
Configuration config = ConfigurationManager.OpenExeConfiguration("TFLManager.exe");
// Get the section in the file.
ConnectionStringsSection section = config.GetSection(sSectionName) as ConnectionStringsSection;
// If the section exists and the section is not readonly, then protect the section.
if (section != null)
{
if (!section.IsReadOnly())
{
// Protect the section.
section.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");
section.SectionInformation.ForceSave = true;
// Save the change.
config.Save(ConfigurationSaveMode.Modified);
}
}
}
launch your Command prompt as an Administrator on the computer you want.
At the Command Prompt, enter:
cd C:\Windows\Microsoft.NET\Framework\v4.0.30319
In case your web Config is located in "D:\Code\EncryptWebConfig" directory path, then enter the following to encrypt the ConnectionString:
ASPNET_REGIIS -pef "connectionStrings" "D:\Code\EncryptWebConfig"
Related
See DGibbs answer below.
I can't have the config file saved with the EXE, as this is present on each user's desktop, so it seems I am unable to store the password in the config file and will have to come up with some other solution.
I have an app that needs to run a CMD command as an administrator. To achieve this, I stored the password in a connection string in app.config:
<connectionStrings>
<add name="mypw" connectionString="PASSWORD" />
</connectionStrings>
I am then able to call this in my Cmd class as a SecureString:
private static SecureString pw()
{
string connectionString = ConfigurationManager.ConnectionStrings["mypw"].ConnectionString;
SecureString ss = new SecureString();
foreach (char c in connectionString)
{
ss.AppendChar(c);
}
return ss;
}
When I run the app from VS on my machine with debugging (F5), it works fine and the password is retrieved. However, when running it in a development environment I see the exception Object Reference not set to an instance of an object, and from my own debugging I can see that this is happening at this line:
string connectionString = ConfigurationManager.ConnectionStrings["mypw"].ConnectionString;
Can anyone please explain why the app is able to retrieve the connection string on my machine but not when deployed elsewhere? Does the app.config file change when publishing the app?
Few things, don't use <connectionStrings>, this is typically used to store credentials for a db connection, it doesn't make sense here. Try using AppSettings within the App.config file e.g
<appSettings>
<add key="mypw" value="password" />
</appSettings>
You can retrieve the value like this:
string pw = ConfigurationSettings.AppSettings["mypw"];
Finally, make sure you have the config file deployed, it should be [ApplicationName].exe.config and not App.Config. If it doesn't appear, check the Copy to output directory setting, make sure it's set to Copy Always.
I'd like to randomly generate an encryption key and password for an SQL Server CE database when it's created, and then save the key in some secure way that would allow the program to open a connection, but not be easily reachable by potential attackers.
I'm working on an offline WPF application that stores certain user and setting information in a local database.
My current implementation is to have one "Device Password" that the user sets up which is used as the encryption key for the generated SQL Server CE database password. The base64 encrypted database password is then saved in a simple .txt settings file. When the application starts up, the user enters the Device Password and that string is used as the decryption key for the saved password. If the resulting string is able to open a connection to the database, the password was correct and the program is opened with full access.
What I'm trying to do now is modify the system to allow multiple users with specific Username/Password credentials to open the program and access the database with varying levels of privilege. The way that I'm trying to achieve this is by handling the user authentication separately, and opening the database regardless of the credentials to load some basic application info.
Below is roughly my current implementation:
var candidateDBPwd = DecryptDatabasePassword(passwordBox.Password, Settings.Instance.EncryptedDatabasePassword);
if (candidateDBPwd.IsNullOrEmpty())
{
// User's password didn't decrypt database password.
return false;
}
if (File.Exists(Constants.DB_FILE))
{
// Normal operation: Try to open the database file to see that
// we've got the correct password.
string databaseArguments = Constants.DB_ARGS_SECURE + candidateDBPwd;
using (var conn = new SqlCeConnection(databaseArguments))
{
try
{
conn.Open();
}
catch (System.Data.SqlServerCe.SqlCeException ex)
{
// Failed to open the database: User's password must have been wrong!
return false;
}
}
I've spent the past few hours researching similar issues and am now beginning to wonder if it's possible. Consensus seems to state that storing passwords or connectionStrings in the App.config file is futile because if you encrypt the sections, you still need to store that key somewhere in code. Most of the existing SO threads on the issue seem to be several years out of date and it seems that that practice has deprecated. Is there some new respectable way to store a local database password? Or would you recommend a different approach to implementing the feature?
For you information here is the code snippet that can be used to encrypt certain sections of app.config. This is machine specific encryption and I think it is most simple and straightforward way to go.
I am using this with Click-once app, so that the config sections are encrypted during the first launch of the app. It means, that it is unecrypted on the publish server, it is downloaded also unencrypted and it is encrypted right after the installation finishes and application is started.
So using this method you have to distribute your files unencrypted and they are enrypted only after the installation is completed. I suppose it can be achieved by running this code during install, it depends on how you plan to install your app.
Also you can use UnprotectSection() to unencrypt previously encrypted section.
static void EncryptConfig()
{
// Encrypt config for ClickOnce deploys on first run
// ClickOnce deploys config into 2 dirs, so the parent dir is traversed to encrypt all
if (ApplicationDeployment.IsNetworkDeployed)
{
// Get paths
Assembly asm = Assembly.GetExecutingAssembly();
string exeName = Path.GetFileName(asm.Location);
string configName = exeName + ".config";
DirectoryInfo parentPath = Directory.GetParent(Directory.GetCurrentDirectory());
// Protect config files
foreach (DirectoryInfo dir in parentPath.GetDirectories())
{
foreach (FileInfo fil in dir.GetFiles())
{
if (fil.Name == configName)
{
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = fil.FullName;
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
ProtectSection(config, "connectionStrings");
config.Save(ConfigurationSaveMode.Modified);
}
}
}
}
}
private static void ProtectSection(Configuration config, string sectionName)
{
ConfigurationSection section = config.GetSection(sectionName);
if (section != null)
{
if (!section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
}
section.SectionInformation.ForceSave = true;
}
else
Tools.LogWarning("Section {1} not found in {0}.",config.FilePath, sectionName);
}
You can store it in registry editor. You mention that your system is offline wpf application .
just want to ask what would be the best way to hide sensitive data (ftp accounts, database connectionstring, etc) in .Net desktop applications.. any suggestions please.. :)
i was aware of putting data in the application and got in mind that what if the application will be deobfuscated or decompiled the hidden data will be expose.
i tried using Application Settings
Properties.Settings.Default.MyConnectionString = theConString;
but still the data can be seend when decompiled.
any suggestions please.
You can encrypt all or part of the app.config file. This is particularly common for protecting database connection strings.
Here is a detailed article about how to to this. In a nutshell, here is the code from there for encrypting the connection string section in app.config:
static void ToggleConfigEncryption(string exeConfigName)
{
// Takes the executable file name without the
// .config extension.
try
{
// Open the configuration file and retrieve
// the connectionStrings section.
Configuration config = ConfigurationManager.
OpenExeConfiguration(exeConfigName);
ConnectionStringsSection section =
config.GetSection("connectionStrings")
as ConnectionStringsSection;
if (section.SectionInformation.IsProtected)
{
// Remove encryption.
section.SectionInformation.UnprotectSection();
}
else
{
// Encrypt the section.
section.SectionInformation.ProtectSection(
"DataProtectionConfigurationProvider");
}
// Save the current configuration.
config.Save();
Console.WriteLine("Protected={0}",
section.SectionInformation.IsProtected);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
During runtime i need to change the app.config file how can i do it using c#
You need to add a reference to System.Configuration to your project. Then you could use code like this to modify your executable's app.config:
// Open App.Config of executable
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Add an Application Setting.
config.AppSettings.Settings.Remove("LastDateFeesChecked");
config.AppSettings.Settings.Add("LastDateFeesChecked", DateTime.Now.ToShortDateString());
// Save the configuration file.
config.Save(ConfigurationSaveMode.Modified);
// Force a reload of a changed section.
ConfigurationManager.RefreshSection("appSettings");
NOTE: This code will not seem to work while debugging. You must run the code in "Release Mode" in order for this to work.
Here's a promising link on CodeProject.
Not sure but try this
set a reference using the namespace
using System.Configuration;
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
AppSettingsSection configSection = config.AppSettings;
try {
if (configSection != null) {
if (configSection.IsReadOnly() == false && configSection.SectionInformation.IsLocked == false) {
configSection.Settings("KeyName").Value = "NewValue";
config.Save();
}
}
}
catch (ConfigurationException ex) {
MessageBox.Show(ex.Message, "Configuration Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
CheckHere
AH.. you do not. Your question ca nbe interpreted as "i dont ahve wrights to write it". This is normal. Application folder is not to be edited by the program or normal users. Store your non-static configuration somewhere else (CommonAppData special folder).
I have an add-on for a commercial ASP.NET website. My add-on requires people to merge entries into their web.config, add/overwrite existing files, and add some DLL files to the bin folder.
Is there a good and safe way to create an installer than can do this with a wizard type of installation? It would really help non-technical people install the add-on easily. Maybe even a web-based installer would be good?
Any help or suggestions would be greatly appreciated.
Had a similar problem...
Web.Config
Created a .NET command line program that you can call from your installer passing it the web.config path and other args to match what I'm trying to do
In the command line program you can then modify the web.config to your needs... Below is an example of setting a connection string & the stmp from address in a web.config
public static void SetConnectionString(string name, string connString, string webConfigPath)
{
string directory = System.IO.Path.GetDirectoryName(webConfigPath);
VirtualDirectoryMapping vdm = new VirtualDirectoryMapping(directory, true);
WebConfigurationFileMap wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
System.Configuration.Configuration webConfig = System.Web.Configuration.WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");
webConfig.ConnectionStrings.ConnectionStrings[name].ConnectionString = connString;
webConfig.Save();
}
public static void SetFromAddress(string email, string webConfigPath)
{
string directory = System.IO.Path.GetDirectoryName(webConfigPath);
VirtualDirectoryMapping vdm = new VirtualDirectoryMapping(directory, true);
WebConfigurationFileMap wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
System.Configuration.Configuration webConfig = System.Web.Configuration.WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");
System.Net.Configuration.MailSettingsSectionGroup mailSettings = (System.Net.Configuration.MailSettingsSectionGroup)webConfig.GetSectionGroup("system.net/mailSettings");
mailSettings.Smtp.From = email;
webConfig.Save();
}
Installer
I used NSIS (http://nsis.sourceforge.net/Main_Page). Use HM NIS Edit as a good starting point as it has a wizard that will generate scripts for you. From there you can modify up the scripts to your needs. In my case I called my command line program after the files where installed. Example NSIS script below.
Section "My Config Wizard" SecWizard
ExecWait '"$INSTDIR\Bin\My.Config.Wizard.exe" "$INSTDIR"'
Return
SectionEnd
Good luck! Need more examples just hit me up. :P
The web.config is the tricky part. Your first installer will deploy an XML file and then a user will change something in it. Meanwhile you have another build where the developer makes changes to the XML and now the installer has to try to figure out how that should merge all back together.
Out of the box, it can't.
2 strategies that I've used over the years:
1) Have the installer smart enough to pick out key pieces of information from the xml before replacing the xml. Then apply the information back.
2) Design your software to have 2 XML files. One that the installer can safely always overwrite and the other to act as an override that the user can modify safely.