我有ASP.NET MVC3应用程序,它使用来自crypt32.dll的一些方法使用P / Invoke。在Windows XP,Windows 7(32位和64位),Windows Server 2003(也是32位和64位)上一切正常,但是当我尝试在Windows Server 2008 R2 x64上设置应用程序时,我的麻烦就开始了。此外,当我尝试在同一台机器上运行VS2010的项目时,它工作正常。服务器安装了最新的更新,IIS 7.5以及所需的所有其他内容。
应用程序没有给出任何错误,只是导致“页面不可用”或有时出现错误503(停止应用程序池)。
以下是我在事件查看器中获得的内容:
Faulting application name: w3wp.exe, version: 7.5.7601.17514, time stamp: 0x4ce7a5f8
Faulting module name: CRYPT32.dll, version: 6.1.7601.17514, time stamp: 0x4ce7b841
Exception code: 0xc0000005
Fault offset: 0x00010cf3
Faulting process id: 0xc4c
Faulting application start time: 0x01cd3f0fac5721fb
Faulting application path: C:\Windows\SysWOW64\inetsrv\w3wp.exe
Faulting module path: C:\Windows\syswow64\CRYPT32.dll
Report Id: ee39118a-ab02-11e1-8d06-000c297e9eda
应用程序池仅由此应用程序使用,它设置为启用32位应用程序,集成管道和正确的.Net版本。 Project是为x86平台构建的(即使我尝试了其他所有可能性),我甚至尝试将所需的DLL添加到项目中,将Copy to Output Directory设置为Always Always,但没有任何帮助。
使用日志我设法弄清楚:
if (!CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, IntPtr.Zero, ref cbData))
{
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
}
DLLImport代码:
[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool CertGetCertificateContextProperty(
IntPtr pCertContext,
uint dwPropId,
IntPtr pvData,
ref uint pcbData
);
任何可能导致问题的想法?
以下是代码的其余部分:
CERT_NAME_BLOB cnbCertificate;
CRYPT_DATA_BLOB certificate;
IntPtr hCertStore = IntPtr.Zero;
IntPtr pCertContext = IntPtr.Zero;
uint cbData = 0;
byte[] encoded = Encode(cert.Subject);
GCHandle pinnedArray = new GCHandle();
pinnedArray = GCHandle.Alloc(cBuffer, GCHandleType.Pinned);
certificate.cbData = cBuffer.Length;
certificate.pbData = pinnedArray.AddrOfPinnedObject();
pinnedArray.Free();
hCertStore = PFXImportCertStore(ref certificate, password, CRYPT_USER_KEYSET | CRYPT_EXPORTABLE);
cnbCertificate.cbData = (uint)encoded.Length;
GCHandle h1;
if (hCertStore != IntPtr.Zero)
{
try
{
h1 = GCHandle.Alloc(encoded, GCHandleType.Pinned);
cnbCertificate.pbData = h1.AddrOfPinnedObject();
dataHandle = GCHandle.Alloc(cnbCertificate, GCHandleType.Pinned);
pCertContext = CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, dataHandle.AddrOfPinnedObject(), IntPtr.Zero);
if (h1 != null) h1.Free();
}
catch (Exception exp)
{
log.Error("Marshall error1: " + exp.Message + " " + Marshal.GetLastWin32Error());
}
finally
{
}
}
if (!CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, IntPtr.Zero, ref cbData))
{
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
}
答案 0 :(得分:2)
我刚刚注意到日志中的异常代码:0xc0000005。这是一种访问冲突,这意味着您提供给方法的指针引用了无效的地址。指针本身可以为null或零,或者它应指向的CERT_CONTEXT结构具有无效数据。
这与ASP.NET或IIS无关,代码或数据中存在错误。也许证书开头是错误的。