【发布时间】:2012-06-05 16:47:30
【问题描述】:
我有 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 版本。项目是为 x86 平台构建的(即使我尝试了所有其他可能性),我什至尝试将所需的 DLL 添加到项目中,将复制到输出目录设置为始终复制,但没有任何帮助。
使用日志我设法找出它在以下位置中断:
if (!CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, IntPtr.Zero, ref cbData))
{
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
}
DLL导入代码:
[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());
}
【问题讨论】:
-
您为什么使用 P/Invoke 而不是 msdn.microsoft.com/en-us/library/… 的 X509Certificate2 等内置证书类?
-
使用 X508Certificate2 不是一个选项,原因有很多,其中一个是我需要 RC4 算法,.NET 框架不支持
-
RC4和证书有什么关系?无论如何,日志中的错误是什么?由于您自己抛出异常,您应该查看 CertGetCertificateContextProperty 和您正在使用的上下文,而不是 ASP.NET 或 P/Invoke。错误代码是什么?它是功能文档中提到的错误代码之一吗?还有什么?
-
抱歉回答缓慢。什么日志?浏览器出现错误 101 (net::ERR_CONNECTION_RESET): Unknown Error,在我的日志文件中没有错误,我只从我已经发布的 IIS 中得到这个错误。对 CertGetCertificateContextProperty 的调用在 try-catch 子句中,但它没有进入 catch 部分,也不会到达 Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());部分在 if 子句中。似乎它只是停止了 IIS。无论如何,感谢您的帮助,如果我解释得不好,对不起。同样,上下文必须良好,并且相同的代码适用于所有其他平台。
-
请解释否决票,我真的认为这家伙有一个合法的 Q,你知道只是一个 DebugDiag 评论或什么的。
标签: c# asp.net .net asp.net-mvc-3 pinvoke