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
389 views
in Technique[技术] by (71.8m points)

c# - Invoking a SOAP web service stopped working after Windows Update

I have a .NET application that invokes a SOAP web service and it has been working for years but it stopped working few days ago after a Windows (Server 2012 R2) security update (there are many and I don't know which one). Microsoft has published some articles about the issue but all the described workarounds didn't work :

https://support.microsoft.com/en-us/help/3155464/ms16-065-description-of-the-tls-ssl-protocol-information-disclosure-vu

https://support.microsoft.com/en-us/help/3069494/cannot-connect-to-a-server-by-using-the-servicepointmanager-or-sslstre

The service that I'm invoking is using SSL3/TLS1.0 and the provider can't/wouldn't upgrade it to TLS1.2. Also I tested my application in old Windows 2008R2 that have no .NET4 updates and it worked as it did before.

My Code :

string url = "https://weblogic_server:7070/app/Service";
string text = "<soapenv:Envelope>...</soapenv:Envelope>";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, error) =>
{
    return true;
};
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
//ServicePointManager.Expect100Continue = false; // did nothing good
//ServicePointManager.UseNagleAlgorithm = false; // did nothing good
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(text);
request.ContentType = "text/xml; encoding='utf-8'";
request.Timeout = 1000000000;
request.ContentLength = bytes.Length;
request.KeepAlive = true;
request.Method = "POST";
using (Stream stm = request.GetRequestStream()) // Exception
{
    using (StreamWriter stmw = new StreamWriter(stm))
    {
        stmw.Write(text);
    }
}
using (StreamReader responseReader = new StreamReader(request.GetResponse().GetResponseStream()))
{
    string resultText = responseReader.ReadToEnd();
    HttpWebResponse resp = (HttpWebResponse)request.GetResponse();
    Console.WriteLine(resp);
    Console.WriteLine(resultText);
}

The Exception code is :

System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: The handshake failed due to an unexpected packet format.
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
   at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.ConnectStream.WriteHeaders(Boolean async)
   --- End of inner exception stack trace ---
   at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
   at System.Net.HttpWebRequest.GetRequestStream()

My question are :
- Is there any other way/workaround to get this invocation work, other than what's described in the articles ?
- The code works fine under .NET2.0 where .NET4.0 is not updated to the .NET4.6, is there a way to force the application to use a specific old System.dll (copied from Windows 2008R2 machine) ? I tried to add it as reference manually but the CLR always uses the GAC's one.
- Is it possible to overload HttpWebRequest and somehow force it to use SSL3 ?

Thanks.

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)
Waitting for answers

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

...