【发布时间】:2019-10-13 07:39:30
【问题描述】:
我正在尝试调用部署在 Linux 服务器上的 Web 服务,该服务器具有来自在 .net 核心中开发并部署在 IIS 服务器(Windows 服务器 2012)上的应用程序的自签名证书。
但是当我尝试调用端点时,会抛出下一个错误:
"Message": "无法建立 SSL 连接,见内部 例外。”, “描述”:“InnerError:System.Security.Authentication.AuthenticationException:身份验证 失败,请参阅内部异常。 ---> System.ComponentModel.Win32Exception: Mensaje recibido inesperado, o bien su formato es wrongo\r\n --- 内部异常堆栈结束 跟踪 ---\r\n 在 System.Net.Security.SslState.StartSendAuthResetSignal(协议令牌 消息,AsyncProtocolRequest asyncRequest,ExceptionDispatchInfo 例外)\r\n 在 System.Net.Security.SslState.CheckCompletionBeforeNextReceive(协议令牌 消息,AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.StartSendBlob(字节 [] 传入,Int32 计数,AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.ProcessReceivedBlob(字节 [] 缓冲区,Int32 计数,AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.StartReadFrame(字节 [] 缓冲区,Int32 readBytes, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)\r\n--- 从先前位置结束堆栈跟踪 抛出异常 ---\r\n 在 System.Net.Security.SslState.ThrowIfExceptional()\r\n at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)\r\n 在 System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult 结果)\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, Func2 endFunction, Action1 endAction, Task1 promise, Boolean requiresSynchronization)\r\n--- 上一个堆栈跟踪的结束 引发异常的位置 ---\r\n at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(流 流,SslClientAuthenticationOptions sslOptions,CancellationToken 取消令牌) |堆栈跟踪:在 System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(流 流,SslClientAuthenticationOptions sslOptions,CancellationToken 取消令牌)\r\n 在 System.Threading.Tasks.ValueTask1.get_Result()\r\n at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Threading.Tasks.ValueTask1.get_Result()\r\n at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1 creationTask)\r\n at System.Threading.Tasks.ValueTask1.get_Result()\r\n at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage 请求,布尔型 doRequestAuth,CancellationToken 取消令牌)\r\n 在 System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage 请求, CancellationToken cancelToken)\r\n 在 System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage 请求,CancellationTokenSource cts,布尔值 disposeCts)\r\n 在 ReservasProxy.Data.APIConnection.CallXMLFormDataApiPostAsyc(字符串 身体)在 C:\gitProjects\ResevasProxy\ReservasProxy\ReservasProxy\Data\APIConnection.cs:line 181\r\n
我已经尝试了下一个解决方案,但没有奏效。
解决方案 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>();
}
}
解决方案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);
}
解决方案 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);
}
我使用 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)
我将证书导入到受信任的根证书颁发机构的 IIS 服务器中。
【问题讨论】:
-
第一个解决方案应该可以工作,它肯定对我有用,更多细节在这里:stackoverflow.com/questions/38138952/…。你只是得到同样的错误吗?你能检查一下回调是否被调用
-
我不太明白您的错误信息,但使用谷歌翻译并不表示这是 CA 信任问题。而是您的服务器以非标准方式或其他方式响应
-
但是,如果我将端点更改为不安全的 HTTP,它就可以工作。第一个解决方案不起作用。
-
你是对的@IlyaChernomordik 我使用 Wireshark 来嗅探流量,我意识到 TLS 版本是错误的。我的客户端尝试使用 TLS 1.2 初始化握手,并且服务器正在关闭连接,因为它期待 TLS v1.0
-
添加了一个关于它的答案