我正在尝试检索 TLS 版本信息。下面的代码使用 HttpClient 成功进行了 HTTP GET 调用。我缺少什么?我在哪里可以从 HttpClient 获取 TLS 版本信息?
我正在做与建议相同的事情协商了哪个 TLS 版本?但这是特定于 WebRequest 的,它与 HttpClient 不同。
static async Task MainAsync()
{
Uri baseURI = new Uri("https://jsonplaceholder.typicode.com/posts/1");
string apiPath = "";
using (var client = new HttpClient())
{
client.BaseAddress = baseURI;
HttpResponseMessage response = await client.GetAsync(apiPath);
Console.WriteLine("HTTP status code: " + response.StatusCode.ToString());
GetSSLConnectionInfo(response, client.BaseAddress.ToString(), apiPath);
}
Console.ReadKey();
}
static async Task GetSSLConnectionInfo(HttpResponseMessage response, string baseURI, string apiPath)
{
using (Stream stream = await response.RequestMessage.Content.ReadAsStreamAsync())
{
BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
Stream CompressedStream = null;
if (stream.GetType().BaseType == typeof(GZipStream))
{
CompressedStream = (GZipStream)stream;
}
else if (stream.GetType().BaseType == typeof(DeflateStream))
{
CompressedStream = (DeflateStream)stream;
}
var objbaseStream = CompressedStream?.GetType().GetProperty("BaseStream").GetValue(stream);
if (objbaseStream == null)
{
objbaseStream = stream;
}
var objConnection = objbaseStream.GetType().GetField("m_Connection", bindingFlags).GetValue(objbaseStream);
var objTlsStream = objConnection.GetType().GetProperty("NetworkStream", bindingFlags).GetValue(objConnection);
var objSslState = objTlsStream.GetType().GetField("m_Worker", bindingFlags).GetValue(objTlsStream);
SslProtocols b = (SslProtocols)objSslState.GetType().GetProperty("SslProtocol", bindingFlags).GetValue(objSslState);
Console.WriteLine("SSL Protocol Used for " + baseURI + apiPath + System.Environment.NewLine + "The TLS version used is " + b);
}
}
我期待 TLS 连接信息,但出现异常。
在引擎盖下HttpClient
使用内部TlsStream
类(如您的示例中的WebRequest
)。我们只需要在另一个位置找到它即可。这是一个例子:
static void Main(string[] args)
{
using (var client = new HttpClient())
{
using (var response = client.GetAsync("https://example.com/").Result)
{
if (response.Content is StreamContent)
{
var webExceptionWrapperStream = GetPrivateField(response.Content, "content");
var connectStream = GetBasePrivateField(webExceptionWrapperStream, "innerStream");
var connection = GetPrivateProperty(connectStream, "Connection");
var tlsStream = GetPrivateProperty(connection, "NetworkStream");
var state = GetPrivateField(tlsStream, "m_Worker");
var protocol = (SslProtocols)GetPrivateProperty(state, "SslProtocol");
Console.WriteLine(protocol);
}
else
{
// not sure if this is possible
}
}
}
}
private static object GetPrivateProperty(object obj, string property)
{
return obj.GetType().GetProperty(property, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj);
}
private static object GetPrivateField(object obj, string field)
{
return obj.GetType().GetField(field, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj);
}
private static object GetBasePrivateField(object obj, string field)
{
return obj.GetType().BaseType.GetField(field, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)