Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
525 views
in Technique[技术] by (71.8m points)

ssl - C# HttpWebRequest SEC_I_RENEGOTIATE Intermittent Errors

I'm working on login / logout functionality using SSL POST calls in a C# (.Net framework 3.5) application. Getting the response from the server via HttpWebRequest::BeginGetResponse() works 80% of the time, but the other 20% it is intermittently throwing:

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

I enabled SSL tracing using the suggested article from another question. That produced two distinct patterns in the request traces.

It seems that during execution, the error:

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

is being received, causing re-init of the security context. When this happens, and it is successful, here is the output (noted that I omitted the actual address):

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

When it fails:

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.

I can of course catch this exception, but what is the proper handling?

Is there a way for my application to prevent (or properly handle) these errors? When it happens it seems to error constantly for a time, but then start to work again after some undetermined number of requests.

Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

(For the original answer, see below.)

What this error usually means is that your client and server are not set to use the same type of encryption. Often, the simplest method of fixing this is explicitly setting the version to use in the client.

If you are using .NET 4.5 or newer, here are the options to try, in order from most secure to least secure:

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

If you are using .NET 4.0 or older, you can only use the last line above, as those versions do not support TLSv1.1 and TLSv1.2. It is highly recommended that you upgrade to .NET 4.5 to take advantage of TLSv1.2 support.

In addition to setting the SecurityProtocol property, you may also have to set: ServicePointManager.Expect100Continue = true;

If none of these settings helps, it likely means that your server only supports SSLv3 (or, even worse, SSLv2). If that is the case, upgrade your server! SSLv3 is broken and should no longer be used.


SSLv3 is NO LONGER considered secure. DO NOT use these settings! While this was the correct answer in 2011, it remains here only for historical reasons.

You need to add the following lines of code before your request:

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

From what I have seen, older versions (.NET 2 and/or Windows xp/2003 and older) used these as the default options but newer versions (.NET 3 and/or Windows Vista/2008 and newer) do not.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...