我有一个使用.NET Framework 4.5.2编写的简单测试客户端,它正在尝试连接到客户的REST Web服务。
代码本身非常简单:
using (var requestHandler = new WebRequestHandler())
{
requestHandler.ClientCertificates.Add(myCertificate);
var url = new Uri(myBaseUrl);
using (var client = new HttpClient(requestHandler) {BaseAddress = url})
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var endPoint = $"api/MyController/Ticket/12345";
var response = client.GetAsync(endPoint).Result;
response.EnsureSuccessStatusCode();
var content = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(JToken.Parse(content).ToString(Formatting.Indented));
}
}
要对此进行测试,我正在本地计算机上运行IIS 10.0,并通过注册表配置SSL / TLS:
\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server\Enabled=1
启用TLS 1.1并禁用TLS 1.2时,如果我将客户端设置ServicePointManager.SecurityProtocol设置为TLS 1.1,则一切正常。
启用TLS 1.1并禁用TLS 1.2时,如果我将客户端设置ServicePointManager.SecurityProtocol设置为TLS 1.2,则会出现异常:
MyTest: System.AggregateException: One or more errors occurred.
---> System.Net.Http.HttpRequestException: An error occurred while sending the request.
---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
---> (Inner Exception #0) System.Net.Http.HttpRequestException: An error occurred while sending the request.
---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
--- End of inner exception stack trace ---<---
这正是我所期望的。
如果我编辑注册表以启用TLS 1.2并禁用1.1,请重新启动并重试,如果我将客户端设置ServicePointManager.SecurityProtocol设置为TLS 1.2,一切正常。
如果我将客户端设置ServicePointManager.SecurityProtocol设置为TLS 1.1,则会出现异常。
所有这些使我相信我的测试客户通常是正确的。正确设置了TLS。
因此,然后我将其放在客户端计算机上,并尝试连接到他们的Web服务。
我们在运行客户端的计算机上运行了一个测试Web服务,因此我们只需要处理一个系统的配置即可。
运行客户端时,如果指定TLS 1.2(这是他们想要使用的),则会出现异常:
MyTest: System.AggregateException: One or more errors occurred.
---> System.Net.Http.HttpRequestException: An error occurred while sending the request.
---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
---> (Inner Exception #0) System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
--- End of inner exception stack trace ---<---
因此,我尝试使用SSL 3,TLS 1.0,TLS 1.1和TLS 1.2来访问我的客户端。无论尝试哪种方式,我都会得到无法创建SSL / TLS安全通道。
请记住-这是在尝试访问运行客户端的计算机上运行的Web服务。
我检查了注册表,当然看起来他们已启用TLS 1.2。而且我知道自从更改注册表以来,他们已经重新启动。
他们正在Windows Server 2008 R2 Datacenter 64位上运行IIS7。
从我坐着的地方看来,尽管已注册并重新启动,但他们的计算机上尚未启用TLS 1.2。
有什么想法吗?
===
让我感到困惑的是,当我通过Chrome浏览器访问该网站时,一切正常。
查看Chrome开发者工具中的安全性详细信息,我们会看到:
此页面是安全的(有效的HTTPS)
与该站点的连接使用的是...颁发的有效的,受信任的服务器证书。
此页面上的所有资源均已安全提供。
与该站点的连接使用TLS 1.2(一个强协议),RSA(一个过时的密钥交换)和带有HMAC-SHA1(一个过时的密码)的AES_128_CBV。