加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 检测用于HttpClient POST或GET调用的TLS版本

发布时间:2020-12-15 22:54:44 所属栏目:百科 来源:网络整理
导读:我正在尝试检索TLS版本信息.我下面的代码使用HttpClient成功进行HTTP GET调用.我错过了什么?从哪里可以从HttpClient获取TLS版本信息? 我有点做与Which TLS version was negotiated?中建议相同的事情但是特定于WebRequest,这与HttpClient不同. static async
我正在尝试检索TLS版本信息.我下面的代码使用HttpClient成功进行HTTP GET调用.我错过了什么?从哪里可以从HttpClient获取TLS版本信息?

我有点做与Which TLS version was negotiated?中建议相同的事情但是特定于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);
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读