2011-06-03 114 views
21

我正在使用C#(.Net框架3.5)应用程序中的SSL POST调用登录/注销功能。获得通过的HttpWebRequest从服务器的响应:: BeginGetResponse()工作80%的时间,而另外20%则抛出间歇:C#HttpWebRequest SEC_I_RENEGOTIATE间歇性错误

The request was aborted: Could not create SSL/TLS secure channel. 

我启用了SSL使用来自另一个问题suggested文章跟踪。这在请求追踪中产生了两种不同的模式。

看来,在执行过程中,出现错误:

System.Net Error: 0 : [3680] Decrypt returned SEC_I_RENEGOTIATE. 

正在接收,导致安全上下文重新初始化。当发生这种情况,这是成功的,这里是输出(注意,我省略了实际的地址):

System.Net Error: 0 : [3680] Decrypt returned SEC_I_RENEGOTIATE. 
System.Net Information: 0 : [3680] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 4bec0d0:4c0a8a8, targetName = [omitted].com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation) 
System.Net Information: 0 : [3680] InitializeSecurityContext(In-Buffer length=0, Out-Buffer length=78, returned code=ContinueNeeded). 
System.Net Information: 0 : [7148] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 4bec0d0:4c0a8a8, targetName = [omitted].com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation) 
System.Net Information: 0 : [7148] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=ContinueNeeded). 
System.Net Information: 0 : [7148] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 4bec0d0:4c0a8a8, targetName = [omitted].com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation) 
System.Net Information: 0 : [7148] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=ContinueNeeded). 
System.Net Information: 0 : [7148] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 4bec0d0:4c0a8a8, targetName = [omitted].com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation) 
System.Net Information: 0 : [7148] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=1259, returned code=ContinueNeeded). 
System.Net Information: 0 : [7148] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 4bec0d0:4c0a8a8, targetName = [omitted].com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation) 
System.Net Information: 0 : [7148] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=ContinueNeeded). 
System.Net Information: 0 : [7148] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 4bec0d0:4c0a8a8, targetName = [omitted].com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation) 
System.Net Information: 0 : [7148] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=OK). 
System.Net Information: 0 : [7148] Remote certificate: [Version] 
    V1 

当它失败:

System.Net Error: 0 : [3680] Decrypt returned SEC_I_RENEGOTIATE. 
System.Net Information: 0 : [3680] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 4bec0d0:4c0ab50, targetName = [omitted].com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation) 
System.Net Information: 0 : [3680] InitializeSecurityContext(In-Buffer length=0, Out-Buffer length=78, returned code=ContinueNeeded). 
System.Net Error: 0 : [3680] Exception in the HttpWebRequest#20730349:: - The request was aborted: Could not create SSL/TLS secure channel. 
System.Net Verbose: 0 : [3680] HttpWebRequest#20730349::EndGetResponse() 
System.Net Error: 0 : [3680] Exception in the HttpWebRequest#20730349::EndGetResponse - The request was aborted: Could not create SSL/TLS secure channel. 

我当然可以捕获这个异常,但什么是适当的处理?

有没有办法让我的应用程序防止(或正确处理)这些错误?当它发生时,它似乎不断出现一段时间的错误,但是在未确定数量的请求后再开始工作。

谢谢!

+0

这是你正在访问什么样的服务器?看起来像.NEt试过一次重新谈判,但服务器不接受握手。 – feroze 2011-06-05 01:27:26

+0

一个Apache Web服务器。我无法直接访问它。以下是标题:{ 内容长度:225 内容类型:text/html 日期:2011年6月3日星期五20:05:26 GMT 服务器:Apache X-Powered-By:PHP/5.2.8 -pl2-gentoo }。 – Stryck 2011-06-06 16:57:29

+0

我遇到完全相同的问题。我还注意到保持活动状态在HTTPS中不起作用,尽管HttpWebRequest配置为保持活动状态,并且它在http中完美工作。我测试了ServicePointManager.SecurityProtocol SSL3和TLS。 – mathieu 2011-08-03 17:45:29

回答

9

(对于原来的答案,见下文)。

这是什么错误通常意味着你的客户端和服务器没有被设置为使用相同的加密类型。通常,解决这个问题的最简单的方法是明确设置要在客户端中使用的版本。

如果您使用的是.NET 4.5或更新版本,这里有尝试的选项,以便从最安全到最不安全的:

  • ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
  • ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
  • ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

如果您使用.NET 4.0或更早版本,则只能使用上面的最后一行,因为这些版本不支持TLSv1.1和TLSv1.2。 强烈建议您升级到.NET 4.5以利用TLSv1.2支持。

除了设置SecurityProtocol财产,你可能还需要设置:ServicePointManager.Expect100Continue = true;

如果没有这些设置的帮助,这可能意味着你的服务器只支持SSLv3的(或者,更糟糕的的SSLv2)。如果是这样的话,升级你的服务器! SSLv3已损坏,不应再使用。


SSLv3不再被认为是安全的。不要使用这些设置!尽管这是2011年的正确答案,但仍然只是出于历史原因。

你需要你的请求之前添加以下代码行:

ServicePointManager.Expect100Continue = true; 
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; 

从我所看到的,使用这些旧版本(.NET 2和/或Windows XP/2003及以上)默认选项,但更新的版本(.NET 3和/或Windows Vista/2008和更新版本)不会。

+0

这个答案可以通过关闭更强大的TLSv1协议来工作。 – EricLaw 2011-08-03 17:24:54

+1

@Moshe:这不会改变我的情况。 – mathieu 2011-08-03 17:49:51

+0

@EricLaw:你如何关闭TLSv1? – mathieu 2011-08-03 17:50:10

4

这不是解释,也不是真正的解决方案:它使用客户端的SSL证书是简单地处理这个问题,我们在我们的例子已经找到的最实用的方法(做一个WCF SOAP请求通过HTTPS与Apache &基于Java的服务器)。

捕获SecurityNegotiationException并现场重试(即不使用msmq重新处理该消息),并在此情况下禁止报告异常。只需添加一个性能计数器或类似的东西,以便跟踪问题是否会变得更糟。

在这一天结束时,这只是您的代码需要处理的那些天生的网络相关问题之一。

+0

我有一个类似的间歇性问题,并采用了像你所建议的方法..问题在于错误倾向于提高,最后,它在每次调用时都会失败..所以这对于自我解决问题是很好的和可取的(那些用户不需要担心的问题),但找到问题的根源仍然是要走的路:) – Luke 2017-10-13 11:06:00

0

我想我会分享我的经验,因为我一直在阅读这个大部分计算器问题最近:

另一种方法来这里面我见过的工作是要考虑HTTP保持活动。使用最新版本的.Net,它使用HTTP 1.1作为默认值,这意味着Keep-Alive被设置为true并且Expect100也处于开启状态。

根据我的经验,这会在资源下游产生粘性,并且在负载均衡器后面不可靠。

两种选择

1)恢复,然后再试一次,这似乎微臭。然而,正如Khanfx所言,网络问题可能会发生:网络的谬误。 TOPAZ是解决此问题的一种方法:https://msdn.microsoft.com/en-us/library/hh680901%28v=pandp.50%29.aspx?f=255&MSPPError=-2147217396

2)通过HttpwebRequest关闭Keep-Alive或者使用HttpClient发出连接关闭标头。

HTH。

+0

downvoter - 谨慎解释为什么? – Jamie 2017-02-01 20:47:12