简体   繁体   English

如何在 .net core 2.1 中忽略 SSL 验证

[英]How to ignore SSL validation in .net core 2.1

I am trying to call a web service that is deployed on a Linux Server that has a self-signed certificate from an application developed in .net core and deployed on an IIS server (Windows server 2012).我正在尝试调用部署在 Linux 服务器上的 Web 服务,该服务器具有来自在 .net core 中开发并部署在 IIS 服务器(Windows 服务器 2012)上的应用程序的自签名证书。

But when I try to call the endpoint the next error is thrown:但是当我尝试调用端点时,会抛出下一个错误:

"Message": "The SSL connection could not be established, see inner exception.", "Description": "InnerError : System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception. ---> System.ComponentModel.Win32Exception: Mensaje recibido inesperado, o bien su formato es incorrecto\\r\\n --- End of inner exception stack trace ---\\r\\n at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)\\r\\n at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)\\r\\n at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)\\r\\n at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)\\r\\n at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)\\r\\n at Sy "Message": "无法建立 SSL 连接,请参阅内部异常。", "Description": "InnerError : System.Security.Authentication.AuthenticationException: 身份验证失败,请参阅内部异常。---> System.ComponentModel.Win32Exception : Mensaje recibido inesperado, o bien su formato es不正确\\r\\n --- 内部异常堆栈跟踪结束---\\r\\n 在 System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo 异常)\\r\\n 在 System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)\\r\\n 在 System.Net.Security.SslState.StartSendBlob(Byte[] 传入,Int32 计数,AsyncProtocolRequest asyncRequest)\\r \\n 在 System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)\\r\\n 在 System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) \\r\\n 在 Sy stem.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)\\r\\n--- End of stack trace from previous location where exception was thrown ---\\r\\n at System.Net.Security.SslState.ThrowIfExceptional()\\r\\n at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)\\r\\n at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)\\r\\n at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)\\r\\n at System.Net.Security.SslStream.<>c.b__47_1(IAsyncResult iar)\\r\\n at System.Threading.Tasks.TaskFactory 1.FromAsyncCoreLogic(IAsyncResult iar, Func 2 endFunction, Action 1 endAction, Task 1 promise, Boolean requiresSynchronization)\\r\\n--- End of stack trace from previous location where exception was thrown ---\\r\\n at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken) | stem.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)\\r\\n--- 从上一个引发异常的位置的堆栈跟踪结束---\\r\\n 在 System.Net.Security.SslState.ThrowIfExceptional() \\r\\n 在 System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)\\r\\n 在 System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)\\r\\n 在 System.Net.Security.SslStream.EndAuthenticateAsClient (IAsyncResult asyncResult)\\r\\n 在 System.Net.Security.SslStream.<>c.b__47_1(IAsyncResult iar)\\r\\n 在 System.Threading.Tasks.TaskFactory 1.FromAsyncCoreLogic(IAsyncResult iar, Func 2 endFunction, Action 1 endAction, Task 1 promise, Boolean requiresSynchronization)\\r\\n--- 从上一个抛出异常的位置结束堆栈跟踪---\\r\\n 在 System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken 取消令牌) | stackTrace : at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)\\r\\n at System.Threading.Tasks.ValueTask 1.get_Result()\\r\\n at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)\\r\\n at System.Threading.Tasks.ValueTask 1.get_Result()\\r\\n at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask 1 creationTask)\\r\\n at System.Threading.Tasks.ValueTask 1.get_Result()\\r\\n at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)\\r\\n at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\\r\\n at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)\\r\\n at ReservasProxy stackTrace : 在 System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancelationToken)\\r\\n 在 System.Threading.Tasks.ValueTask 1.get_Result()\\r\\n at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)\\r\\n at System.Threading.Tasks.ValueTask cancelationToken 1.get_Result()\\r\\n at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)\\r\\n at System.Threading.Tasks.ValueTask 1.get_Result()\\r\\n 在 System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask 1 creationTask)\\r\\n at System.Threading.Tasks.ValueTask 1.get_Result()\\r\\n 在 System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancelationToken)\\r\\n 在 System.Net.Http.RedirectHandler。 SendAsync(HttpRequestMessage request, CancellationToken cancelationToken)\\r\\n 在 System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)\\r\\n 在 ReservasProxy .Data.APIConnection.CallXMLFormDataApiPostAsyc(String body) in C:\\gitProjects\\ResevasProxy\\ReservasProxy\\ReservasProxy\\Data\\APIConnection.cs:line 181\\r\\n .Data.APIConnection.CallXMLFormDataApiPostAsyc(String body) in C:\\gitProjects\\ResevasProxy\\ReservasProxy\\ReservasProxy\\Data\\APIConnection.cs:line 181\\r\\n

I already try the next solutions but they didn´t work.我已经尝试了下一个解决方案,但它们没有用。

Solution 1 :解决方案1:

          using (var httpClientHandler = new HttpClientHandler())
        {
            httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
            // Make your request...
            //send request
            using (var httpClient = new HttpClient(httpClientHandler))
            {

                var content = new StringContent(body, Encoding.UTF8, "application/soap+xml");
                HttpResponseMessage response = await httpClient.PostAsync(_url, content);
                //var res = await response.Content.ReadAsAsync<T>();


            }


        }

Solution 2:解决方案2:

            //send request
        using (var httpClient = new HttpClient())
        {
             ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
            ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
            var content = new StringContent(body, Encoding.UTF8, "application/soap+xml");
            HttpResponseMessage response = await httpClient.PostAsync(_url, content);

        }

Solution 3: Trying to import the certificate and then make the call but still not working.解决方案 3:尝试导入证书,然后拨打电话,但仍然无法正常工作。

const string certPath = @"C:\soaProdcer.cer";    
var handler = new HttpClientHandler
            {
                ClientCertificateOptions = ClientCertificateOption.Manual,
                SslProtocols = System.Security.Authentication.SslProtocols.Tls
            };
            handler.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate(certPath));

            //send request
            using (var httpClient = new HttpClient(handler))
            {
                var content = new StringContent(body, Encoding.UTF8, "application/soap+xml");
                HttpResponseMessage response = await httpClient.PostAsync(_url, content);

            }

I got the certificate using OpenSSL我使用 OpenSSL 获得了证书

>openssl s_client -showcerts -connect serversoa:443

No client certificate CA names sent
---
SSL handshake has read 774 bytes and written 493 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : RC4-SHA
    Session-ID: 4E0F69C75B8F041101562F7E9B3EA349
    Session-ID-ctx:
    Master-Key: 61A916A9B8AF26281B5F7A0138DF5E4C2A4B83995E0B3FDD2274BAD0D8E3C2B5E98AA7CCB48A6543F6814C2540B18848
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1558979896
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)

I imported the certificate into the IIS server into the trusted root certification authorities.我将证书导入到受信任的根证书颁发机构的 IIS 服务器中。

I don't remember exactly the link of Microsoft tell you about this.我不记得微软的链接告诉你这个。 Your above solutions work well with older asp.net core version.您的上述解决方案适用于较旧的 asp.net 核心版本。 This is my solution with the latest ASP.NET Core that I've implemented for my project.这是我为我的项目实现的最新 ASP.NET Core 的解决方案。 I hope it helps you.我希望它能帮助你。

services.AddHttpClient<IYourService, YourService>()
    .ConfigurePrimaryHttpMessageHandler(sp => new HttpClientHandler
    {
        AllowAutoRedirect = false,
        ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true,
        SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12
    });

Please also read about HttpClientFactory: https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests另请阅读 HttpClientFactory: https : //docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests

As Ilya said it wasn´ta problem with the certificate CA authority.正如 Ilya 所说,这不是 CA 证书颁发机构的问题。 The problem was that the client was trying to use a different version of TLS (1.2) The solution was to specify the TLS version.问题是客户端试图使用不同版本的 TLS (1.2) 解决方案是指定 TLS 版本。

using (var httpClientHandler = new HttpClientHandler())
            {
                httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
                httpClientHandler.SslProtocols = System.Security.Authentication.SslProtocols.Tls;
                //send request
                using (var httpClient = new HttpClient(httpClientHandler))
                {
                    var content = new StringContent(body, Encoding.UTF8, "application/soap+xml");
                    HttpResponseMessage response = await httpClient.PostAsync(_url, content);

                }
            }

I used Wireshark to sniffer the traffic and see what was going on...我使用 Wireshark 来嗅探流量,看看发生了什么......

Client sending hello with version, not supported客户端发送带有版本的问候,不支持客户端发送带有版本的问候,不支持

The server closing the connection服务器关闭连接在此处输入图片说明


After finishing the test in my computer and the tests were successful I deploy the application on IIS server.在我的电脑上完成测试并且测试成功后,我将应用程序部署到 IIS 服务器上。 When I started testing my application on the server it started throwing the same exception as before.当我开始在服务器上测试我的应用程序时,它开始抛出与以前相同的异常。

Why?为什么?

It turned out that the server had deactivated the cipher (RC4) As the next figure shows.结果证明服务器已停用密码 (RC4),如下图所示。 在此处输入图片说明

So if you are using Windows like me you just need to check the ciphers that the certificate is using.因此,如果您像我一样使用 Windows,则只需检查证书使用的密码即可。 As I mentioned before the Linux server was using a CR4 cipher in the certificate正如我之前提到的,Linux 服务器在证书中使用了 CR4 密码

The error does not indicate a trouble with the certificate CA authority, but rather a response from a server that is not expected for the TLS to be established.该错误并不表示证书 CA 机构有问题,而是来自服务器的响应,该响应不是预期的 TLS 建立。

As the author has figured out the client supported 1.2 and the server 1.0 and it caused the trouble.由于作者已经弄清楚客户端支持1.2和服务器1.0并且它引起了麻烦。

PS I would recommend using only TLS 1.2 if that is the option with browser support that you need to handle. PS 如果这是您需要处理的浏览器支持选项,我建议仅使用 TLS 1.2。 (only old versions do not support 1.2.) (只有旧版本不支持 1.2。)

Use the sample below from here 这里使用下面的示例

var httpClientHandler = new HttpClientHandler();
// Return `true` to allow certificates that are untrusted/invalid
httpClientHandler.ServerCertificateCustomValidationCallback = 
    HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var httpClient = new HttpClient(httpClientHandler);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM