将 HttpClient 和 HttpWebRequest 用于 Https TLS1.2
Using HttpClient & HttpWebRequest for Https TLS1.2
在控制台应用程序中,尝试访问配置了 TLS 1.2 的 "https" 端点时。
在 C# 中
在使用 HttpClient 时,我从端点
获得了成功响应
HttpClient httpClient = new HttpClient();
//specify to use TLS 1.2 as default connection
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
httpClient.BaseAddress = new Uri("HTTPSENDPOINT");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var content = new StringContent("POSTDATA");
var task = httpClient.PostAsync("/Token", content);
task.Wait();
Console.WriteLine(task.Result.Content.ReadAsStringAsync().Result.ToString());
但是当使用 HttpWebRequest 时
var request = (HttpWebRequest)WebRequest.Create("HTTPSENDPOINT/Token");
var postData = "POSTDATA";
var data = Encoding.ASCII.GetBytes(postData);
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream()) // Getting Error in GetRequestStream() method call
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
我低于错误
The request was aborted: Could not create SSL/TLS secure channel.
请指导我在使用 HttpWebRequest 时做错了什么?
你的问题看起来很接近这个问题The request was aborted: Could not create SSL/TLS secure channel
我注意到他们在不将 SecurityProtocolType.Ssl3 添加到您已添加的其他项时遇到了问题。尝试像评价最高的答案那样实施枚举协议。
在调用WebRequest.Create
方法之前,您需要设置SecurityProtocol
属性。
更新:
让我添加一些细节来解释为什么这是正确的。
查看 referencesource.microsoft.com 中 WebRequest.Create(string)
方法的源代码。
return值为:
return Create(new Uri(requestUriString), false);
现在,让我们看一下 Create(Uri, bool)
方法,它 return 是 WebRequestPrefixElement.Creator.Create(Uri)
中的一些对象。
Creator
是 WebRequestPrefixElement
内部的 属性,类型为 IWebRequestCreate
。
在您的情况下,IWebRequestCreate
将是一个 HttpRequestCreator
对象。
查看HttpRequestCreator.Create
方法的代码:
public WebRequest Create( Uri Uri ) {
//
// Note, DNS permissions check will not happen on WebRequest
//
return new HttpWebRequest(Uri, null);
}
最后,让我们看一下 HttpWebRequest
构造函数。
您会在那里看到很长的代码,但真正重要的是这一行:
SslProtocols = (SslProtocols)ServicePointManager.SecurityProtocol;
因此 SecurityProtocol
值被分配给名为 SslProtocols
的 属性。
因此,现在很明显,当您调用 Create
方法时,使用 SecurityProtocol
并保存到 HttpWebRequest 对象中,因此在 调用之后更改 SecurityProtocol
Create
不会更改 HttpWebRequest 对象使用的协议。
在控制台应用程序中,尝试访问配置了 TLS 1.2 的 "https" 端点时。
在 C# 中 在使用 HttpClient 时,我从端点
获得了成功响应 HttpClient httpClient = new HttpClient();
//specify to use TLS 1.2 as default connection
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
httpClient.BaseAddress = new Uri("HTTPSENDPOINT");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var content = new StringContent("POSTDATA");
var task = httpClient.PostAsync("/Token", content);
task.Wait();
Console.WriteLine(task.Result.Content.ReadAsStringAsync().Result.ToString());
但是当使用 HttpWebRequest 时
var request = (HttpWebRequest)WebRequest.Create("HTTPSENDPOINT/Token");
var postData = "POSTDATA";
var data = Encoding.ASCII.GetBytes(postData);
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream()) // Getting Error in GetRequestStream() method call
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
我低于错误
The request was aborted: Could not create SSL/TLS secure channel.
请指导我在使用 HttpWebRequest 时做错了什么?
你的问题看起来很接近这个问题The request was aborted: Could not create SSL/TLS secure channel
我注意到他们在不将 SecurityProtocolType.Ssl3 添加到您已添加的其他项时遇到了问题。尝试像评价最高的答案那样实施枚举协议。
在调用WebRequest.Create
方法之前,您需要设置SecurityProtocol
属性。
更新:
让我添加一些细节来解释为什么这是正确的。
查看 referencesource.microsoft.com 中 WebRequest.Create(string)
方法的源代码。
return值为:
return Create(new Uri(requestUriString), false);
现在,让我们看一下 Create(Uri, bool)
方法,它 return 是 WebRequestPrefixElement.Creator.Create(Uri)
中的一些对象。
Creator
是 WebRequestPrefixElement
内部的 属性,类型为 IWebRequestCreate
。
在您的情况下,IWebRequestCreate
将是一个 HttpRequestCreator
对象。
查看HttpRequestCreator.Create
方法的代码:
public WebRequest Create( Uri Uri ) {
//
// Note, DNS permissions check will not happen on WebRequest
//
return new HttpWebRequest(Uri, null);
}
最后,让我们看一下 HttpWebRequest
构造函数。
您会在那里看到很长的代码,但真正重要的是这一行:
SslProtocols = (SslProtocols)ServicePointManager.SecurityProtocol;
因此 SecurityProtocol
值被分配给名为 SslProtocols
的 属性。
因此,现在很明显,当您调用 Create
方法时,使用 SecurityProtocol
并保存到 HttpWebRequest 对象中,因此在 调用之后更改 SecurityProtocol
Create
不会更改 HttpWebRequest 对象使用的协议。