我正在尝试使用CryptUnprotectData
将使用CryptProtectData
保护的密码读入SecureString
并使用它来连接数据库。我可以输出正确的密码,但尝试创建新的SqlConnection
之后会失败并显示以下内容:
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:
仅仅为CryptUnprotectData
调用SqlConnection
就足够了,连接本身不需要使用返回的SecureString
。
我正在使用from here中描述的扩展方法this post进行我的最小重复:
class Program
{
const string ProtectedSecret = /* SNIP - base 64 encoded protected data here */;
static void Main()
{
// calling AppendProtectedData breaks the following SqlConnection
// without the following line the application works fine
new SecureString().AppendProtectedData(Convert.FromBase64String(ProtectedSecret));
using (var conn = new SqlConnection("Server=(localdb)\\MSSqlLocalDb;Trusted_Connection=true"))
using (var cmd = new SqlCommand("select 1", conn))
{
conn.Open();
cmd.ExecuteNonQuery();
}
}
}
如果我在之前创建新的SqlConnection
我加载密码,我可以在应用程序的持续时间内创建新的SqlConnection
,因为它似乎使用相同的SqlConnectionFactory
,但这意味着作为一种解决方法,我必须在应用程序开始时做这样的事情:
new SqlConnection().Dispose();
...我想避免。
以下内容无效:
CryptProtectFlags
。{/ li>的CryptUnprotectData
RuntimeHelpers.PrepareConstrainedRegions()
。Windows 10,VS Enterprise 2015,控制台应用程序(.NET 4.6.1)
UPDATE:在另一个线程中运行数据保护代码会产生一个类似的异常,其根本原因不同:
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:
答案 0 :(得分:4)
有趣的是,错误代码是:
<script type="text/javascript">
$('a.print-pdf-link').click(function () {
var prtContent = document.getElementById("page-content");
var WinPrint = window.open('', '', 'left=0,top=0,width=800,height=900,toolbar=0,scrollbars=0,status=0');
WinPrint.document.write(prtContent.innerHTML);
WinPrint.document.close();
WinPrint.focus();
setTimeout(() => WinPrint.print(), 1000);
WinPrint.close();
});
</script>
调用internal static PerformanceCounterLib GetPerformanceCounterLib(string machineName, CultureInfo culture) {
SharedUtils.CheckEnvironment();
string lcidString = culture.LCID.ToString("X3", CultureInfo.InvariantCulture);
if (machineName.CompareTo(".") == 0)
machineName = ComputerName.ToLower(CultureInfo.InvariantCulture);
else
machineName = machineName.ToLower(CultureInfo.InvariantCulture);
...
的行会导致异常。
您只需调用代码
即可重现相同的行为ComputerName.ToLower(CultureInfo.InvariantCulture)
以某种方式在TextInfo
类
new SecureString().AppendProtectedData(Convert.FromBase64String(ProtectedSecret));
string lower = "Something".ToLower(CultureInfo.InvariantCulture);
如果在this.m_dataHandle = CompareInfo.InternalInitSortHandle(m_textInfoName, out handleOrigin);
函数之前未调用此函数,将返回无效数据。
这似乎是框架中的一个错误。您可以将其提交给Microsoft。在此期间,您可以事先调用此行以防止错误。
CryptUnprotectData
答案 1 :(得分:2)
我最近遇到了类似的症状,使用http://www.griffinscs.com/?p=12中的相同代码:对CryptUnprotectData
的任何调用都会导致某些无关代码出现异常。有趣的是,故障只发生在Windows 10机器上;相同的代码在Windows 7机器上运行良好。
我通过将szDataDescr
和CryptProtectData
中的CryptUnprotectData
参数的声明从string
更改为IntPtr
并传递{{1}来解决问题在两次调用中代替IntPtr.Zero
。