.NET Framework 4.8对接巴西Itaú银行API遇SSL/TLS安全通道创建失败
部署到Windows Server 2019 IIS后,.NET Framework 4.8项目调用Itaú银行API时出现SSL/TLS安全通道创建失败异常
我正在对接巴西Itaú银行的API,需完成认证后才能执行后续操作。但将项目部署到Windows Server 2019标准版的IIS后,.NET Framework 4.8项目触发异常:"请求已中止: 无法创建SSL/TLS安全通道。"
项目为VB.NET WebForms架构,包含一个.NET Framework 4.8项目和一个.NET Framework 2.0项目,4.8项目引用2.0项目。本地使用Visual Studio 2022调试完全正常,但发布到服务器后卡在认证环节。
服务器已安装.NET Framework 4.8运行时,IIS应用池的.NET CLR版本设置为4.0.30319。我尝试了两种请求发送方式,均出现相同错误,相关代码及异常栈信息如下:
.NET Framework 2.0相关代码
Public Sub New() ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateServerCertificate) ServicePointManager.SecurityProtocol = CType(&HC00, Net.SecurityProtocolType) End Sub Public Function ValidateServerCertificate(ByVal sender As Object, ByVal certificate As X509Certificate, ByVal chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean Return True End Function
.NET Framework 4.8认证代码(HttpClient方式)
Private ReadOnly Property Certificado As X509Certificate2 Get If m_Certificado Is Nothing Then Dim assembly As Assembly = Assembly.GetExecutingAssembly() Using stream As Stream = assembly.GetManifestResourceStream(GetType(AppModule), "certificado.pfx") If stream Is Nothing Then Throw New ApplicationException("Certificado não encontrado.") End If Dim rawData(CInt(stream.Length)) As Byte stream.Read(rawData, 0, rawData.Length) m_Certificado = New X509Certificate2(rawData, "PASSWORD") End Using End If Return m_Certificado End Get End Property Public Function EnviarAutenticacao() As RetornoRequisicao Dim handler As New WebRequestHandler() Dim httpContent As StringContent = Nothing Dim responseMessage As HttpResponseMessage = Nothing Dim resposta As New RetornoRequisicao Dim sClient As String = "" Dim contentData As String = "grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET" Try handler.ClientCertificates.Add(Certificado) 'With the 2 lines below, removing them from the constructor or leaving them in the constructor and removing from here handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12 handler.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateServerCertificate) Using client As New HttpClient(handler) Try httpContent = New StringContent(contentData, TextEncoding, "application/x-www-form-urlencoded") responseMessage = client.PostAsync(URLAutenticacao, httpContent).GetAwaiter().GetResult() If responseMessage.IsSuccessStatusCode Then resposta.Status = CInt(HttpStatusCode.OK) Else resposta.Status = CInt(responseMessage.StatusCode) End If resposta.Conteudo = responseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult() Finally Try sClient = JsonConvert.SerializeObject(client, ErrorSerializerSettings) Catch End Try End Try End Using Catch ex As Exception Dim sbMensagem As New StringBuilder sbMensagem.AppendLine("Erro ao Autenticar") Try sbMensagem.AppendLine($"Handler:{vbCrLf}{JsonConvert.SerializeObject(handler, ErrorSerializerSettings)}") Catch End Try If Not String.IsNullOrEmpty(sClient) Then sbMensagem.AppendLine($"Client:{vbCrLf}{sClient}") End If Try sbMensagem.AppendLine($"Certificate:{vbCrLf}{JsonConvert.SerializeObject(Certificado, ErrorSerializerSettings)}") Catch End Try If Not String.IsNullOrEmpty(contentData) Then sbMensagem.AppendLine($"Content Data:{vbCrLf}{contentData}") End If If httpContent IsNot Nothing Then Try sbMensagem.AppendLine($"Http Content:{vbCrLf}{JsonConvert.SerializeObject(httpContent, ErrorSerializerSettings)}") Catch End Try End If If responseMessage IsNot Nothing Then Try sbMensagem.AppendLine($"Response Message:{vbCrLf}{JsonConvert.SerializeObject(responseMessage, ErrorSerializerSettings)}") Catch End Try End If Try sbMensagem.AppendLine($"Resposta:{vbCrLf}{JsonConvert.SerializeObject(resposta, ErrorSerializerSettings)}") Catch End Try Throw New ApplicationException(sbMensagem.ToString, ex) End Try Return resposta End Function
.NET Framework 4.8认证代码(HttpWebRequest方式)
Protected Overrides Function EnviarAutenticacao() As RetornoRequisicao Dim request As HttpWebRequest = Nothing Dim requestResponse As HttpWebResponse = Nothing Dim resposta As New RetornoRequisicao Try request = CType(WebRequest.Create(URLAutenticacao), HttpWebRequest) request.ContentType = "application/x-www-form-urlencoded" request.Method = TipoEnvioAutenticacao request.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateServerCertificate) Dim dataBody As String = "grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET" Dim body As Byte() = Encoding.ASCII.GetBytes(dataBody) request.ContentLength = body.Length Dim myWriter As Stream = Nothing request.ClientCertificates.Add(Certificado) myWriter = request.GetRequestStream() myWriter.Write(body, 0, body.Length) requestResponse = CType(request.GetResponse(), HttpWebResponse) resposta.Conteudo = New StreamReader(requestResponse.GetResponseStream()).ReadToEnd() If requestResponse.StatusCode >= 200 AndAlso requestResponse.StatusCode <= 299 Then resposta.Status = CInt(HttpStatusCode.OK) Else resposta.Status = CInt(requestResponse.StatusCode) End If Catch ex As Exception Dim sbMensagem As New StringBuilder sbMensagem.AppendLine("Erro ao Autenticar") Try sbMensagem.AppendLine($"Request:{vbCrLf}{JsonConvert.SerializeObject(request, ErrorSerializerSettings)}") Catch End Try If requestResponse IsNot Nothing Then Try sbMensagem.AppendLine($"Request Response:{vbCrLf}{JsonConvert.SerializeObject(requestResponse, ErrorSerializerSettings)}") Catch End Try End If Try sbMensagem.AppendLine($"Resposta:{vbCrLf}{JsonConvert.SerializeObject(resposta, ErrorSerializerSettings)}") Catch End Try Throw New ApplicationException(sbMensagem.ToString, ex) End Try Return resposta End Function
异常栈信息
错误信息: Erro ao Autenticar(认证出错) Handler: { "AuthenticationLevel": 1, "ImpersonationLevel": 4, "AllowPipelining": true, "UnsafeAuthenticatedConnectionSharing": false, "MaxResponseHeadersLength": 64, "ReadWriteTimeout": 300000, "CachePolicy": { "Level": 1 }, "ContinueTimeout": "00:00:00.3500000", "ClientCertificates": [ { "RawData": "RAW_DATA" } ], "ServerCertificateValidationCallback": null, "CheckCertificateRevocationList": false, "DefaultProxyCredentials": null, "MaxConnectionsPerServer": 2147483647, "Properties": {}, "ServerCertificateCustomValidationCallback": null, "SslProtocols": 0, "SupportsAutomaticDecompression": true, "SupportsProxy": true, "SupportsRedirectConfiguration": true, "UseCookies": true, "CookieContainer": { "Capacity": 300, "Count": 0, "MaxCookieSize": 4096, "PerDomainCapacity": 20 }, "ClientCertificateOptions": 0, "AutomaticDecompression": 0, "UseProxy": true, "Proxy": null, "PreAuthenticate": false, "UseDefaultCredentials": false, "Credentials": null, "AllowAutoRedirect": true, "MaxAutomaticRedirections": 50, "MaxRequestContentBufferSize": 2147483647 } Client: { "DefaultRequestHeaders": [], "BaseAddress": null, "Timeout": "00:01:40", "MaxResponseContentBufferSize": 2147483647 } Certificate: { "RawData": "RAW_DATA" } Content Data: grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET Http Content: { "Headers": [ { "Key": "Content-Type", "Value": [ "application/x-www-form-urlencoded; charset=utf-8" ] }, { "Key": "Content-Length", "Value": [ "127" ] } ] } Resposta: { "Status": 0, "Conteudo": null } Exception ToString: System.Net.Http.HttpRequestException: 发送请求时出错。 ---> System.Net.WebException: 请求已中止: 无法创建SSL/TLS安全通道。 at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context) at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar) --- 内部异常堆栈跟踪结束 --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at SIARM.NFSE.Data.ArrecadacaoPIXAPIItau.EnviarAutenticacao() (System.ApplicationException) at SIARM.NFSE.Data.ArrecadacaoPIXAPIItau.EnviarAutenticacao() at SIARM.NFSE.Data.ArrecadacaoPIXAPI.Autenticar() 错误信息: 发送请求时出错。(System.Net.Http.HttpRequestException) at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at ArrecadacaoPIXAPIItau.EnviarAutenticacao() 错误信息: 请求已中止: 无法创建SSL/TLS安全通道。(System.Net.WebException) at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context) at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)
内容的提问来源于stack exchange,提问作者Celso
相关产品推荐
相关产品推荐

