Hiding Important Data - c#

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);
}
}

Related

Encryption ConnectionStrings App.config

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"

Securely Storing Database Password

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 .

Declaring per-user (roaming user) configuration settings for a plugin DLL?

How can I setup support for per (roaming) user configuration settings for a particular plugin .DLL loaded from another application?
I have a .DLL that is loaded as add-in/plugin from another application, and want to persist configuration settings particular for this one independently of the main application that loads it, based on machine, .dll (=executable), roaming user or user profile.
I have found the System.Configuration.ExeConfigurationFileMap class that looks likely to provide what I need, but I can't figure out how to setup the right paths specific for my (plugin) application.
What code I have so far is:
public class MyConfigurationSettings : ConfigurationSection
{
public static MyConfigurationSettings GetSection (ConfigurationUserLevel ConfigLevel)
{
string configFile = Assembly.GetAssembly(typeof(MyConfigurationSettings)).Location + ".config";
ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
configFileMap.ExeConfigFilename = configFile;
configFileMap.LocalUserConfigFilename = <localUserConfigFile>; // ??? What filename to place here and how to get it based on the current environment ???
configFileMap.RoamingUserConfigFilename = <roamingUserConfigFile>; // ???;
System.Configuration.Configuration Config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigLevel);
// ...
}
}
Can anyone point me into the right direction? The available documentation and search results are too confusing or insufficient for me to get this right. Sorry , if this seems to be a silly question, but my C# (.NET) skills are going to get rusty after 4+ years not using it for earning daily bread.
I also believe it's not primarily an issue about configuration settings management, but how to get paths for installation specific application instance configurations.
You set RoamingUserConfigFilename = RoamingName.config and put it under Roaming Profile:
%AppData%\[AppName]\[Vendor]\[CodedPath]\[Version]\RoamingName.config
Also you set LocalUserConfigFilename = LocalName.config and put it under Local Profile:
%LocalAppData%\[AppName]\[Vendor]\[CodedPath]\[Version]\LocalName.config
Now calling
ConfigurationManager.OpenMappedExeConfiguration(
exeMap,
ConfigurationUserLevel.PerUserRoamingAndLocal);
config will be read in the following order:
Source on MSDN blogs.
For samples search for User.config under c:\Users\[User]\AppData. Also see CP article.
Code Sample:
public static MyConfigurationSettings GetSection (ConfigurationUserLevel ConfigLevel)
{
try
{
string appDataPath = System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string localDataPath = System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
System.Configuration.ExeConfigurationFileMap exeMap = new ExeConfigurationFileMap();
exeMap.ExeConfigFilename = System.IO.Path.Combine(appDataPath, #"MyCompany\MyPlugin\Default.config");
exeMap.RoamingUserConfigFilename = System.IO.Path.Combine(appDataPath, #"MyCompany\MyPlugin\Roaming.config");
exeMap.LocalUserConfigFilename = System.IO.Path.Combine(localDataPath, #"MyCompany\MyPlugin\Local.config");
System.Configuration.Configuration Config = ConfigurationManager.OpenMappedExeConfiguration(exeMap,ConfigLevel);
return (MyConfigurationSettings)Config.GetSection("MyConfigurationSettings");
}
catch (Exception ex) {
// ...
}
return null; // or throw an appropriate exception
}
Generally load the configuration from the special folder where you put it in and put it into one of the roaming (i.e. non local) locations. The OS handles the rest as per roaming specifications.
The usage of ConfigSections is totally irrelevant unless there is a very very special need to use the config file for that. In any .NET project I have seen in the last 10 years this file was never used for user specific settings.

C# app.config read and write

Can we save data or some text in app.config file
if yes then it is persistence or temporary ?
for example if i store last access date time in app.config file and then close/Exit the application after the some time/days/years when i start my application is it possible that the last access date time I can retrieve. If yes then how please explain with code ....
Thanks,
Raj
here is my code ..
Trying to retrieve date time from config file..
But show error object not set to be an object like...
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (email.To.Contains(Email) && DateTime.Compare(email.UtcDateTime.Date, Convert.ToDateTime(config.AppSettings.Settings["ModificationDate"].Value)) > 0)
Here i store /save the date time in app.config file.
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration
(ConfigurationUserLevel.None);
// Add an Application Setting.
config.AppSettings.Settings.Add("ModificationDate", DateTime.Now + " ");
// Save the changes in App.config file.
config.Save(ConfigurationSaveMode.Modified);
// Force a reload of a changed section.
ConfigurationManager.RefreshSection("appSettings");
Console.WriteLine("Last Update :"+config.AppSettings.Settings["ModificationDate"].Value);
Console.ReadLine();
Please suggest me why it show me an error that object not set am done any mistake please ans...
You can create a settings xml file to do this.
In VS go to your project properties -> Settings, then write a value in.
In code, you can get/set that value using
Properties.Settings.Default.YourVariable = 0;
If you are setting the value make sure to save it
Properties.Settings.Default.Save();
See here for a good tutorial.
I would use a custom configuration section to create your configuration type - last access date time. you can create more complex hierarchy configuration and strongly-typed.
Again, it depend on your requirement and design if you need to do that. otherwise, standard file storage(txt/xml) would also allow you to do that. I personally normally using app.config for application specific level(appearance/fonts/servername etc.) configuration rather than transactional configuration.
for e.g
public class LastAccessConfigurationSection : System.Configuration.ConfigurationSection {
[ConfigurationProperty("LastAccess")]
public string LastAccess{
get { return (string)this["LaunchTime"]; }
set { this["LaunchTime"] = value; }
}
}
you can have a static class to manage the life-cycle that would allow you to persist the change.
public static LastAccessConfigurationSection Config { get; internal set; }
public static void Initialize() {
Config = ConfigurationManager.GetSection("LastAccess") as LastAccessConfigurationSection;
}
You could use App.config for storage like any other file and it will persist and be available the next time you run your program. That is the nature of file storage in general. I would suggest that you store that data in a separate file or database. I will not, however, write the code for you.

give write access using C# on runtime

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).

Categories