如何获得 HttpClient POST 请求中使用的协商 TLS 版本
How can I get negotiated TLS version used in HttpClient POST requests
我正在尝试获取在我的 HttpClient SendAsync 调用中使用的 TLS 版本信息。我已经尝试过此 link 中的方法,但是当我 运行 它处于调试模式时,我发现在获取 SslProtocol 属性 时出现对象处置异常。有什么方法可以阻止 .net 处理对象属性,直到我阅读它们。
代码如下:
public bool ExecuteAsync()
{
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
}
}
}
return true;
}
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);
}
此外,我在其他一些代码中有 运行 上面 link 中的解决方案,并且它正在运行。我发现的不同之处在于,当我在主线程中完成所有工作时,其他代码正在启动新线程来执行 SendAsync 调用。另外我在某处读到,对上面 link.
中使用的 SendAsync 方法使用“using”语句不是好的做法
另外,有没有其他方法可以获取TLS版本信息。我听说可以从 .net framework 日志中读取它,但我不知道该怎么做。
如果我能获得与 TLS 流相关的其他信息,如散列算法和密码算法,那就太好了。另外,我用的是.net framework 4.6.1,对问题有影响吗?
借助@MarkoW 此处给出的代码 ,我找到了一种读取代码中 System.Net 痕迹的方法。
我得打电话
ExecuteWithEnabledSystemNetLogging(SourceLevels webTraceSourceLevel, Action actionToExecute, params TraceListener[] listener).
对于我的情况,输入变量如下。
webTraceSourceLevel 是 SourceLevels.Information
actionToExecute 是我发送 HttpClient 请求的方法,我需要 system.net 跟踪,分配给 Action 对象。
监听器是 TextWriterTraceListener myTextListener = new TextWriterTraceListener(stream)
// 其中 stream 是一个流对象,其中我的 system.net tracing 与我通过的操作相关,稍后我将其转换为字符串。
有了这个我得到了 tls 版本和其他密码相关信息。
我正在尝试获取在我的 HttpClient SendAsync 调用中使用的 TLS 版本信息。我已经尝试过此 link
代码如下:
public bool ExecuteAsync()
{
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
}
}
}
return true;
}
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);
}
此外,我在其他一些代码中有 运行 上面 link 中的解决方案,并且它正在运行。我发现的不同之处在于,当我在主线程中完成所有工作时,其他代码正在启动新线程来执行 SendAsync 调用。另外我在某处读到,对上面 link.
中使用的 SendAsync 方法使用“using”语句不是好的做法另外,有没有其他方法可以获取TLS版本信息。我听说可以从 .net framework 日志中读取它,但我不知道该怎么做。
如果我能获得与 TLS 流相关的其他信息,如散列算法和密码算法,那就太好了。另外,我用的是.net framework 4.6.1,对问题有影响吗?
借助@MarkoW 此处给出的代码 ,我找到了一种读取代码中 System.Net 痕迹的方法。
我得打电话
ExecuteWithEnabledSystemNetLogging(SourceLevels webTraceSourceLevel, Action actionToExecute, params TraceListener[] listener).
对于我的情况,输入变量如下。
webTraceSourceLevel 是 SourceLevels.Information
actionToExecute 是我发送 HttpClient 请求的方法,我需要 system.net 跟踪,分配给 Action 对象。
监听器是 TextWriterTraceListener myTextListener = new TextWriterTraceListener(stream)
// 其中 stream 是一个流对象,其中我的 system.net tracing 与我通过的操作相关,稍后我将其转换为字符串。
有了这个我得到了 tls 版本和其他密码相关信息。