【问题标题】:C# HttpWebRequest SEC_I_RENEGOTIATE Intermittent ErrorsC# HttpWebRequest SEC_I_RENEGOTIATE 间歇性错误
【发布时间】:2011-06-03 21:12:19
【问题描述】:

我正在使用 C#(.Net 框架 3.5)应用程序中的 SSL POST 调用来开发登录/注销功能。通过 HttpWebRequest::BeginGetResponse() 从服务器获取响应在 80% 的情况下有效,但另外 20% 的时间是间歇性抛出:

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

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

好像在执行过程中报错:

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.

我当然可以捕捉到这个异常,但正确的处理方式是什么?

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

谢谢!

【问题讨论】:

  • 您正在访问什么样的服务器?看起来 .NEt 曾尝试重新协商,但服务器不接受握手。
  • 一个 Apache Web 服务器。我无法直接访问它。这是标题:{ Content-Length: 225 Content-Type: text/html Date: Fri, 03 Jun 2011 20:05:26 GMT 服务器:Apache X-Powered-By: PHP/5.2.8-pl2-gentoo } .
  • 我遇到了完全相同的问题。我还注意到 keep-alive 在 HTTPS 中不起作用,尽管 HttpWebRequest 配置了 keep-alive 并且它在 http 中完美运行。我已经测试过 ServicePointManager.SecurityProtocol SSL3 和 TLS。
  • 我添加了一大笔赏金以获得不同的答案。 Expect100Continue = true 对我不起作用,我真的需要解决这个问题,这是我们的网络应用程序遇到的最大问题。我得到完全相同的Decrypt returned SEC_I_RENEGOTIATE 错误,并且症状与上述相同“似乎有一段时间不断出错,但随后又开始工作”。这是在 IIS 7.5 64 位 Web 服务器上,每天有几百个用户,错误每天发生 1 到 3 次。
  • 您访问 Apache 日志吗?此外,Apache 是集群/负载平衡的还是单台服务器? .NET 客户端的同样问题,无论您是从一台服务器还是从集群客户端访问此 Apache 服务器

标签: c# ssl error-handling httpwebrequest


【解决方案1】:

(原始答案见下文。)

此错误通常意味着您的客户端和服务器未设置为使用相同类型的加密。通常,解决此问题的最简单方法是显式设置要在客户端中使用的版本。

如果您使用的是 .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 及更高版本)没有.

【讨论】:

  • @Moshe :这对我来说没有任何改变。
  • @EricLaw - 不幸的是,我使用过的一些网络服务似乎不支持 TLSv1。
  • 在我的应用程序中,这两个选项都是默认设置的。没有影响。
  • @TweeZz 考虑到 80% 的时间在同一台服务器上工作,这几乎绝对不是问题。
  • 这对我不起作用,因为我使用的 API 不支持 SSLv3。我能够使用它确实有效:ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
【解决方案2】:

这不是解释,也不是真正的解决方案:它只是我们在案例中发现的处理这个问题的最实用的方法(使用带有 Apache 和基于 Java 的服务器)。

捕获 SecurityNegotiationException 并在现场重试(即,如果使用 msmq,则不要重新处理消息),并在这种情况下禁止报告异常。只需添加一个性能计数器或类似的简单工具,您就可以跟踪问题是否变得更糟。

归根结底,这只是您的代码需要处理的与生俱来的网络相关问题之一。

【讨论】:

  • 我有一个类似的间歇性问题,并使用了你建议的方法。问题是错误往往会引发,最后,它在每次尝试调用时都会失败。所以这很好并希望有自我解决的麻烦(用户不需要担心的那些),但找到问题的根源仍然是要走的路:)
【解决方案3】:

我想我会分享我的经验,因为我最近一直在阅读有关此问题的大多数 stackoverflow 问题:

我见过的另一种解决方法是考虑 HTTP Keep-Alive。对于最新版本的 .Net,它默认使用 HTTP 1.1,这意味着 Keep-Alive 设置为 true,Expect100 也设置为 on。

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

两种选择

1) 恢复并重试,看起来有点臭。然而,正如 Khanfx 提到的,网络问题可能会发生:网络谬误。 TOPAZ 是解决这个问题的一种方法:https://msdn.microsoft.com/en-us/library/hh680901%28v=pandp.50%29.aspx?f=255&MSPPError=-2147217396

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

HTH。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-20
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    • 1970-01-01
    相关资源
    最近更新 更多