无法使用TLSv1.2协议连接WebService?C#调用报错求助
问题描述
此前用C#访问某WebService一切正常,对方将安全协议改为TLSv1.2后,无法访问服务,返回错误:
Unhandled Exception: System.Net.WebException: The underlying
connection was closed: Unexpected error on a send. --->
System.IO.IOException: Unable to read data from transport connection:
An existing connection was forced to be canceled by the remote host.
---> System.Net.Sockets.SocketException: An existing connection was forced to be canceled by the remote host
相关代码如下:
class Program { public static string arquivopfx; public static string senha; public static void Main(String[] args) { int counter = 0; string line; System.IO.StreamReader file = new System.IO.StreamReader(@"assina.config"); while((line = file.ReadLine()) != null) { if (counter == 3) { break; } if (counter == 0) { arquivopfx = line; } if (counter == 1) { senha = line.Trim(); } counter++; } file.Close(); Execute(); } /// <summary> /// Execute a Soap WebService call /// </summary> /// doc.Save("c:\\try.xml"); public static void Execute() { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3; HttpWebRequest request = CreateWebRequest(); XmlDocument soapEnvelopeXml = new XmlDocument(); soapEnvelopeXml.Load(@"SOAP_request.xml"); soapEnvelopeXml.PreserveWhitespace = true; request.ServicePoint.Expect100Continue = false; try { File.Delete(@"SOAP_response.xml"); using (Stream stream = request.GetRequestStream()) { soapEnvelopeXml.Save(stream); } using (WebResponse response = request.GetResponse()) { using (StreamReader rd = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("UTF-8"))) { // ljê a resposta para uma string string soapResult = rd.ReadToEnd(); Console.WriteLine(soapResult); // grava a string no disco using (StreamWriter writer = new StreamWriter("SOAP_response.xml", false, Encoding.Default)) { writer.WriteLine(soapResult); } } } } catch (WebException ex) { //string message = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd(); throw ex; } } /// <summary> /// Create a soap webrequest to [Url] /// </summary> /// <returns></returns> public static HttpWebRequest CreateWebRequest() { string url = "https://webservices.envio.esocial.gov.br/servicos/empregador/enviarloteeventos/WsEnviarLoteEventos.svc"; HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url); webRequest.Headers.Add("SOAPAction","http://www.esocial.gov.br/servicos/empregador/lote/eventos/envio/v1_1_0/ServicoEnviarLoteEventos/EnviarLoteEventos"); webRequest.ContentType = "text/xml;charset=\"utf-8\""; webRequest.Accept = "text/xml"; webRequest.KeepAlive = false; webRequest.Method = "POST"; webRequest.Timeout = 30000; webRequest.ClientCertificates.Add(new X509Certificate2(arquivopfx, senha)); return webRequest; } }
解决方案
问题根源是代码指定的安全协议未包含TLSv1.2,对方服务已强制使用该协议,导致握手失败,连接被远程主机关闭。
针对.NET 4.5及以上版本
修改Execute方法中的ServicePointManager.SecurityProtocol配置,添加Tls12并移除已废弃的Ssl3:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls;
针对.NET 4.0版本
由于.NET 4.0原生枚举无Tls12,需手动定义枚举值后再配置:
const SecurityProtocolType Tls12 = (SecurityProtocolType)3072; ServicePointManager.SecurityProtocol = Tls12 | SecurityProtocolType.Tls;
修改后重新调用WebService,即可正常建立TLSv1.2连接。
内容的提问来源于stack exchange,提问作者DQL SISTEMAS
相关产品推荐
相关产品推荐

