I used following method to encrypt connectionstrings
section of my app.config
in my WinForms
project(I'm using Code First EF in my project):
public static void EncryptConfig(string exeConfigName)
{
var config = ConfigurationManager.OpenExeConfiguration(exeConfigName);
var section = config.GetSection("connectionStrings") as ConnectionStringsSection;
if (section != null || !section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
config.Save();
}
}
and I use following method to decrypt the connectionstrings
section, too:
public static void DecryptConfig(string exeConfigName)
{
var config = ConfigurationManager.OpenExeConfiguration(exeConfigName);
var section = config.GetSection("connectionStrings") as ConnectionStringsSection;
if (section != null && section.SectionInformation.IsProtected)
section.SectionInformation.UnprotectSection();
}
this method works in my machine, but when I deploy my application to another machine I get following exception:
System.Configuration.ConfigurationErrorsException: Failed to decrypt using provider 'DataProtectionConfigurationProvider'. Error message from the provider: Key not valid for use in specified state. (Exception from HRESULT: 0x8009000B) (D:\l4test\Level4UI.exe.config line 82) ---> System.Runtime.InteropServices.COMException: Key not valid for use in specified state. (Exception from HRESULT: 0x8009000B)
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode)
at System.Configuration.DpapiProtectedConfigurationProvider.DecryptText(String encText)
at System.Configuration.DpapiProtectedConfigurationProvider.Decrypt(XmlNode encryptedNode)
at System.Configuration.ProtectedConfigurationSection.DecryptSection(String encryptedXml, ProtectedConfigurationProvider provider)
at System.Configuration.Internal.InternalConfigHost.System.Configuration.Internal.IInternalConfigHost.DecryptSection(String encryptedXml, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedConfigSection)
at System.Configuration.Internal.DelegatingConfigHost.DecryptSection(String encryptedXml, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedConfigSection)
at System.Configuration.Internal.DelegatingConfigHost.DecryptSection(String encryptedXml, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedConfigSection)
at System.Configuration.BaseConfigurationRecord.CallHostDecryptSection(String encryptedXml, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedConfig)
at System.Configuration.BaseConfigurationRecord.DecryptConfigSection(ConfigXmlReader reader, ProtectedConfigurationProvider protectionProvider)
--- End of inner exception stack trace ---
at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)
at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
at System.Configuration.Configuration.GetSection(String sectionName)
at IASCo.Infrastructure.Common.Utilities.Configuration.ConfigurationEncryption.DecryptConfig(string exeConfigName)
In this thread, Jeremy said:
You need to publish with the section decrypted. The key that is used to encrypt/decrypt is machine specific.
My app will be installed on a network share and run from there but there will be more than one person who may access the app from their work stations, How can I specify a single key to decrypt the connectionString
section that will work from all the machines used to access the app.
I'm looking for a way to do this job(encrypt in my machine and decrypt in user's machines) using c#.
Your code looks fine to me - other than needing to change from the user of
if (section != null || !section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
config.Save();
}
to
if (section != null || !section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection("RsaProtectionConfigurationProvider");
config.Save();
}
When you do create the RSA keys make sure you use the -exp switch to enable exporting of the keys as per the docs: https://msdn.microsoft.com/en-us/library/yxw286t2.aspx
aspnet_regiis -pc "KeysetName"–exp
As stated by the earlier answerers. In addition to this, if the users of the application are on an IIS network, you may user ASP.NET Impersonation vis your organisations access control lists (ACLs). This will allow you to remove the need to authenticate on a machine level, which doesn't suit all applications. See: https://msdn.microsoft.com/en-us/library/xh507fc5.aspx
User contributions licensed under CC BY-SA 3.0