C# 建立SSL\TLS连接(X509Chain.Build())花费的时间太长
我发现,当我使用HttpWebRequest建立SSL\TLS连接时,调用C# 建立SSL\TLS连接(X509Chain.Build())花费的时间太长,c#,.net,ssl,system.net.httpwebrequest,C#,.net,Ssl,System.net.httpwebrequest,我发现,当我使用HttpWebRequest建立SSL\TLS连接时,调用 request.GetRequestStream() 在启用stacktrace的情况下启用跟踪时,我发现2s将查找poxy,因此我在app.config中禁用了它: <system.net> <defaultProxy enabled="false" useDefaultCredentials="false"> <proxy/> <bypasslist/>
request.GetRequestStream()
在启用stacktrace的情况下启用跟踪时,我发现2s将查找poxy,因此我在app.config中禁用了它:
<system.net>
<defaultProxy enabled="false" useDefaultCredentials="false">
<proxy/>
<bypasslist/>
<module/>
</defaultProxy>
</system.net>
在检查方法体之后,我找到了对X509Chain.Build()的调用,构建证书链花费了将近25秒
有趣的是,当您构造新的HttpWebReqest并再次尝试(无需重新启动应用程序)时,执行请求需要几毫秒的时间
有人能建议怎么做吗?缓存请求不是一个选项,从应用程序运行开始它应该是快速的
更新:
我在X509Chain.BuildChain()中找到了需要30秒的调用,它是:
CAPISafe中声明的方法为:
[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool CertGetCertificateChain([In] IntPtr hChainEngine, [In] SafeCertContextHandle pCertContext, [In] ref System.Runtime.InteropServices.ComTypes.FILETIME pTime, [In] SafeCertStoreHandle hAdditionalStore, [In] ref CAPIBase.CERT_CHAIN_PARA pChainPara, [In] uint dwFlags, [In] IntPtr pvReserved, [In, Out] ref SafeCertChainHandle ppChainContext);
所以,它是加密API函数
还是不知道下一步该怎么办
更新:
我已尝试禁用CRL和OCSP检查,但仍然无效:
<runtime>
<generatePublisherEvidence enabled="false"/>
</runtime>
通常,路径构建意味着构建一个有效的路径,这需要检查自颁发证书以来是否有任何证书 为了检查当前吊销状态,您需要来自CRL或OCSP响应程序的最新信息。如果在路径验证请求的设置过程中没有明确提供正确的CRL,那么如果CRL的URL列在 如果网络速度较慢、路径较长或CRL较大,则这可能需要一些时间。也许这正是你这么长时间的原因。由于它在第一次之后运行得很快,我猜在第一次尝试时会下载一些大型CRL并缓存以供后续使用 或者,如果在中公布了某个库,则该库可能会自动联系。但是,有些库需要显式配置才能使用OCSP,或者更喜欢OCSP而不是CRL 如果要验证来自多个不同颁发者的几个证书,请尝试在OCSP可用的地方使用它。该协议速度快,响应小,通常包含关于单个证书的信息,而不是发布者曾经撤销的每个证书的信息
如果要验证来自单个颁发者的多个证书,请在后台急切地下载该颁发者的CRL,并将其保留到到期。然后将CRL传递到路径构建过程中,这样就不必在用户等待时下载它。最后我找到了问题的根源。我在事件日志中启用了CAPI2日志记录,并在尝试从以下位置下载证书信任列表时发现NetworkTimeoutException: 所以,这就是防火墙问题。
您可以阅读有关调查过程和使用的技术的信息。谢谢您的回复。似乎这不是一个选项,正如我从代码中看到的,X509Chain的实例是通过以下方式创建的:
c X509Chain chain=new X509Chain{ChainPolicy={RevocationMode=X509RevocationMode.NoCheck,VerificationFlags=X509VerificationFlags.IgnoreInvalidName}代码>还有,证书的OCSP列表是空的。现在,我发现即使禁用了CRL和OCSP检查,应用程序也会尝试连接到这个IPs:8.26.222.254:http 199.93.57.254:http 206.33.54.126:http 4.26.235.254:http 8.27.7.126:http,也许你是对的。但是在哪里应该禁用它呢?这真的是禁用它的好理由吗?已签出。链中没有具有CRL分发点的证书,并且列表中没有任何证书具有任何OCSP。所以,问题是,它在哪里以及为什么会连接?@hkurabko奇怪。这些都是3级内容交付网络中的服务器。那些连接慢吗?您是否能够使用WireShark或其他工具观察请求,以了解它们是什么以及它们是如何执行的?另外,禁用撤销检查通常不是您应该做的事情。但是,关闭它们以尝试隔离问题是一个很好的举措。FWIW,#1根据应用程序的Authenticode签名(如果有)关闭应用程序的证据生成#2关闭Authenticode签名的Authenticode吊销检查(仅在少数情况下使用)。两者都不适用于SSL客户端证书吊销检查。Microsoft的一位开发人员也有一篇关于此的帖子:
[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool CertGetCertificateChain([In] IntPtr hChainEngine, [In] SafeCertContextHandle pCertContext, [In] ref System.Runtime.InteropServices.ComTypes.FILETIME pTime, [In] SafeCertStoreHandle hAdditionalStore, [In] ref CAPIBase.CERT_CHAIN_PARA pChainPara, [In] uint dwFlags, [In] IntPtr pvReserved, [In, Out] ref SafeCertChainHandle ppChainContext);
<runtime>
<generatePublisherEvidence enabled="false"/>
</runtime>