I am using Visual Studio and I am very confused about the best way to store configuration strings. I am creating a Windows Forms Application. I need very basic security -- I don't want the password to be readable in app.config but I am not concerned about someone disassembling my code in order to figure it out.
So, in the Data Source Wizard, I said "Don't Save Password" and then I put the following code in Settings.Designer.CS:
public string MyConnectionString { get { return ((string)("Data Source=SQLSERVER\\ACCOUNTING;Initial Catalog=ACCOUNTING;User ID=MyUser;Password=28947239SKJFKJF")); } } I realize that this isn't the best solution but I can't think of a better one. I would appreciate anyone's help and input on this.
Thanks --
Missy.
4 Answers
Answers 1
You can use RsaProtectedConfigurationProvider to encrypt your ConnectionStrings Section. Here is short sample how to encrypt and decrypt this section (Just take note, start your Visual Studio as Administrator):
Primary web config:
<?xml version="1.0"?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup> <connectionStrings> <add name="MyConnKey" connectionString="Data Source=SQLSERVER\\ACCOUNTING;Initial Catalog=ACCOUNTING;User ID=MyUser;Password=28947239SKJFKJF" /> </connectionStrings> <appSettings> <add key="DD" value="567_Access"/> </appSettings> </configuration> Code:
static void Main(string[] args) { Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath); ConfigurationSection section = config.GetSection("connectionStrings") as ConnectionStringsSection; if (!section.SectionInformation.IsProtected) { Console.WriteLine("Protecting connection strings..."); section.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider"); } else { Console.WriteLine("Unprotecting connection strings..."); section.SectionInformation.UnprotectSection(); } section.SectionInformation.ForceSave = true; config.Save(ConfigurationSaveMode.Full); var cs = System.Configuration.ConfigurationManager.ConnectionStrings["MyConnKey"]; Console.WriteLine(cs.ConnectionString); Console.ReadLine(); } And here is how coded config looks like:
<?xml version="1.0"?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup> <connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider"> <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" /> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" /> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <KeyName>Rsa Key</KeyName> </KeyInfo> <CipherData> <CipherValue>js82TLzdIfcdD51g2Us8Nv2eWTSval7oi2Xl+OJsL2c2hUDrm21YG/v1yhuB5Ag8/Uubm9gjmQYcPImo8VOXXDZxEW/HIYNbbkDsopbAyyXNGkHtTrEqz80nqAyipn+Y5QpwXKxFJoaEMPaPdO5juXYd2SPdGaFMBg4m2+drSy6bvXnloz+GIXKbL9QNdxg8br1S8ALUxXsu4F52sKda6J/Sk+I9SBf85XK/JKaHQFoHghf1/m58Zh0hIhci3R6wwGDC3mVG/NcL3tWKpga3ndQ+57FBezsWWOMKyLFPMZG7NkNvBaNG0fYJm2+ApKme1gGil2GGivxySP4evL4hRw==</CipherValue> </CipherData> </EncryptedKey> </KeyInfo> <CipherData> <CipherValue>r28s2mSZTEwb99SIJH7kozBR8RkY8LkxzVLm/VExEwc3aLqSJgqJGrNY6f4mtvCT9ZIYV/QjErt9weQNYSZxyou4RXAq1W8yYnzv+7NCvgOgKvAQh/p+iQidh13SmnC6UCtSrMp3HeRSFNj1y1sF2TGYVpWqWA9NAEBsOyYr0ey6S6/fUFrLAy7mcCkawemmDRvxqF7YnG+LoL9Bh59/l++BhTYlMQvz/stHb5mA6bfKgZYbYDA9KEr5mdrr9t8GGzrk3vNW5s723bKZuiqUWiZfWklY2a2NuONDKj4FG3cAUwCdXq2OzIBFVnXSBgrMo+4GCgQar7delms+bvFOnjozrHdKHJLoahithwPEmDuiM4SJJAZHXKTpFrmv4o+YT68i9xs0iUy0p/hnb5lJv3ITCmEnsOmewn7xIsoPcZMEK54kAtoyjXt2H3QR7KdI3Sf4R6X3rHYr4BerF0UatdP8q5ppLi6uYT/epDi0qTFgf9aDuOW2zDc1TYzFEhBrg4sr2DqqTJWgpyI0yVcq76ZmSTwa53ReyvHFuLkMadijJuUe+u5zPj0BDR6kl8vXN0OzXjby8Uw=</CipherValue> </CipherData> </EncryptedData> </connectionStrings> <appSettings> <add key="DD" value="567_Access"/> </appSettings> </configuration> Take notice that in this case decrypt will work only on machine where encrypt was processed in first place. For more info please visit RsaProtectedConfigurationProvider
Answers 2
You may use the standard Rijndael algorithm to encrypt the entire connection string. You only need to keep the algorithm's password and the salt values in the code level (you may consider them as application constants).
App Config:-
<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="DbContext" connectionString="7ryM3BFhWTwVGpeMWK0pMMujIwj7j+GvrJf7xewEW4Pd+uq0W8aSq85eaEp6+O2Gom98iVNHcyeuaG/93B2y/uJKyHmSnsBlHT3UtBpnT8Lx3OragLK5EXtIiVl38uq10bMga055qq1dACR6XQQeIQ==" providerName="System.Data.SqlClient" /> </connectionStrings> </configuration> Code:-
class Program { private static string _password = "0B6854E7-20AA-4B0E-978A-410152AA1B41"; static void Main(string[] args) { var connection = System.Configuration.ConfigurationManager.ConnectionStrings["DbContext"].ConnectionString; var salt = "Pa$$w0rd"; var plainConnection = DecryptRijndael(connection, salt); //var encrypted = EncryptRijndael(connection, salt); } public static string EncryptRijndael(string text, string salt) { if (string.IsNullOrEmpty(text)) throw new ArgumentNullException("text"); using(var aesAlg = NewRijndaelManaged(salt)) using(var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV)) using (var msEncrypt = new MemoryStream()) { using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) using (var swEncrypt = new StreamWriter(csEncrypt)) swEncrypt.Write(text); return Convert.ToBase64String(msEncrypt.ToArray()); } } public static string DecryptRijndael(string cipherText, string salt) { if (string.IsNullOrEmpty(cipherText)) throw new ArgumentNullException("cipherText"); if (!IsBase64String(cipherText)) throw new Exception("The cipherText input parameter is not base64 encoded"); using (var aesAlg = NewRijndaelManaged(salt)) using (var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV)) { var cipher = Convert.FromBase64String(cipherText); using (var msDecrypt = new MemoryStream(cipher)) using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) using (var srDecrypt = new StreamReader(csDecrypt)) return srDecrypt.ReadToEnd(); } } private static bool IsBase64String(string base64String) { base64String = base64String.Trim(); return (base64String.Length % 4 == 0) && Regex.IsMatch(base64String, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None); } private static RijndaelManaged NewRijndaelManaged(string salt) { if (salt == null) throw new ArgumentNullException("salt"); var saltBytes = Encoding.ASCII.GetBytes(salt); using (var key = new Rfc2898DeriveBytes(_password, saltBytes)) { var aesAlg = new RijndaelManaged(); aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); aesAlg.IV = key.GetBytes(aesAlg.BlockSize / 8); return aesAlg; } } } Hope this helps.
Answers 3
If you want to have unreadable connection string or specific string then put it in registry..
In App.config:
<appSettings> <add key="dbname" value="dbname"/> <add key="username" value="uname"/> ..... and so on </appSettings> Then to your code behind:
string dbname = ConfigurationManager.AppSettings["dbname"].ToString(); Then make a full connection here:
String yourConnectionString = "DataSorce="DataSourceFromConfig + " " + Password from registry or password from appconfig that encrypted + "" + and so on: It's all depend on you..
Answers 4
you could develop a separate tool. This tool take your connection string as input and returns a encrypted string. You must use algorithm for encrypting the string.
After getting encrypted connection string you put it into the config file. When you access the database in the program. You need to decrypt the connection string with same salt password which is use for encrypting the string.
0 comments:
Post a Comment