I am trying to use CryptUnprotectData to read a password protected with CryptProtectData in SecureString and use it to connect to the database. I can get the correct password, but try to create a new SqlConnection , after which the following will not be done:
System.TypeInitializationException was unhandled HResult=-2146233036 Message=The type initializer for 'System.Data.SqlClient.SqlConnection' threw an exception. Source=System.Data TypeName=System.Data.SqlClient.SqlConnection StackTrace: at System.Data.SqlClient.SqlConnection..ctor() at System.Data.SqlClient.SqlConnection..ctor(String connectionString, SqlCredential credential) at System.Data.SqlClient.SqlConnection..ctor(String connectionString) at ProtectedSqlTest.Program.Main() in C:\Git\ProtectedSqlTest\ProtectedSqlTest\Program.cs:line 16 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: HResult=-2146233036 Message=The type initializer for 'System.Data.SqlClient.SqlConnectionFactory' threw an exception. Source=System.Data TypeName=System.Data.SqlClient.SqlConnectionFactory StackTrace: at System.Data.SqlClient.SqlConnection..cctor() InnerException: HResult=-2146233036 Message=The type initializer for 'System.Data.SqlClient.SqlPerformanceCounters' threw an exception. Source=System.Data TypeName=System.Data.SqlClient.SqlPerformanceCounters StackTrace: at System.Data.SqlClient.SqlConnectionFactory..cctor() InnerException: HResult=-2147024809 Message=The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG)) Source=mscorlib StackTrace: at System.Globalization.TextInfo.InternalChangeCaseString(IntPtr handle, IntPtr handleOrigin, String localeName, String str, Boolean isToUpper) at System.Globalization.TextInfo.ToLower(String str) at System.String.ToLower(CultureInfo culture) at System.Diagnostics.PerformanceCounterLib.GetPerformanceCounterLib(String machineName, CultureInfo culture) at System.Diagnostics.PerformanceCounterLib.IsCustomCategory(String machine, String category) at System.Diagnostics.PerformanceCounter.InitializeImpl() at System.Diagnostics.PerformanceCounter.set_RawValue(Int64 value) at System.Data.ProviderBase.DbConnectionPoolCounters.Counter..ctor(String categoryName, String instanceName, String counterName, PerformanceCounterType counterType) at System.Data.ProviderBase.DbConnectionPoolCounters..ctor(String categoryName, String categoryHelp) at System.Data.SqlClient.SqlPerformanceCounters..ctor() at System.Data.SqlClient.SqlPerformanceCounters..cctor() InnerException:
Just call CryptUnprotectData to fail SqlConnection , the connection itself does not need to use the returned SecureString .
I am using extension methods here , as described in this post for my minimal replay:
class Program { const string ProtectedSecret = ; static void Main() {
If I create a new SqlConnection before uploading the password, I can create a new SqlConnection penalty for the entire duration of the application, since it seems to use the same SqlConnectionFactory , but that means that I have to do something as a workaround similar at the beginning of the application:
new SqlConnection().Dispose();
... which I would like to avoid.
The following steps do not help:
- Debugging vs Release build
- Visual Studio debugging versus command line
- The
CryptProtectFlags change that is passed to CryptUnprotectData . - Removing
RuntimeHelpers.PrepareConstrainedRegions() from the protection method.
Windows 10, VS Enterprise 2015, console application (.NET 4.6.1)
UPDATE: Running data protection code on other threads gives a similar exception with another main reason:
System.TypeInitializationException was unhandled HResult=-2146233036 Message=The type initializer for 'System.Data.SqlClient.SqlConnection' threw an exception. Source=System.Data TypeName=System.Data.SqlClient.SqlConnection StackTrace: at System.Data.SqlClient.SqlConnection..ctor() at System.Data.SqlClient.SqlConnection..ctor(String connectionString, SqlCredential credential) at System.Data.SqlClient.SqlConnection..ctor(String connectionString) at ProtectedSqlTest.Program.Main() in C:\Git\ProtectedSqlTest\ProtectedSqlTest\Program.cs:line 17 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: HResult=-2146233036 Message=The type initializer for 'System.Data.SqlClient.SqlConnectionFactory' threw an exception. Source=System.Data TypeName=System.Data.SqlClient.SqlConnectionFactory StackTrace: at System.Data.SqlClient.SqlConnection..cctor() InnerException: HResult=-2146233036 Message=The type initializer for 'System.Data.SqlClient.SqlPerformanceCounters' threw an exception. Source=System.Data TypeName=System.Data.SqlClient.SqlPerformanceCounters StackTrace: at System.Data.SqlClient.SqlConnectionFactory..cctor() InnerException: BareMessage=Configuration system failed to initialize HResult=-2146232062 Line=0 Message=Configuration system failed to initialize Source=System.Configuration StackTrace: at System.Configuration.ClientConfigurationSystem.EnsureInit(String configKey) at System.Configuration.ClientConfigurationSystem.PrepareClientConfigSystem(String sectionName) at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName) at System.Configuration.ConfigurationManager.GetSection(String sectionName) at System.Configuration.PrivilegedConfigurationManager.GetSection(String sectionName) at System.Diagnostics.DiagnosticsConfiguration.Initialize() at System.Diagnostics.DiagnosticsConfiguration.get_SwitchSettings() at System.Diagnostics.Switch.InitializeConfigSettings() at System.Diagnostics.Switch.InitializeWithStatus() at System.Diagnostics.Switch.get_SwitchSetting() at System.Data.ProviderBase.DbConnectionPoolCounters..ctor(String categoryName, String categoryHelp) at System.Data.SqlClient.SqlPerformanceCounters..ctor() at System.Data.SqlClient.SqlPerformanceCounters..cctor() InnerException: HResult=-2147024809 Message=Item has already been added. Key in dictionary: 'MACHINE' Key being added: 'MACHINE' Source=mscorlib StackTrace: at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) at System.Collections.Hashtable.Add(Object key, Object value) at System.Configuration.Internal.InternalConfigRoot.GetConfigRecord(String configPath) at System.Configuration.ClientConfigurationSystem.EnsureInit(String configKey) InnerException: