Determine negotiated TLS version
.NET Framework 4.7 applications use TLS 1.2 by default. However, it is critical to determine the specific TLS version negotiated during secure communications. Here's how to do it:
Method 1: Use reflection
This technique involves using reflection to access the internal GetRequestStream()
properties of the GetResponseStream()
or TlsStream
returned stream. The TlsStream
class exposes the SslState
attribute, which provides access to the SslProtocol
properties.
<code class="language-csharp">using System.IO.Compression; using System.Net; using System.Reflection; using System.Security.Authentication; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(decodedUri); using (Stream requestStream = request.GetRequestStream()) { SslProtocols sslProtocol = ExtractSslProtocol(requestStream); // 检查SSL版本,如有必要采取适当的措施 } private SslProtocols ExtractSslProtocol(Stream stream) { BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic; Stream metaStream = stream; // 处理GZip或Deflate流 if (stream is GZipStream) metaStream = (stream as GZipStream).BaseStream; else if (stream is DeflateStream) metaStream = (stream as DeflateStream).BaseStream; var tlsStream = metaStream.GetType().GetProperty("Connection", bindingFlags).GetValue(metaStream); if (!(bool)tlsStream.GetType().GetProperty("UsingSecureStream", bindingFlags).GetValue(tlsStream)) return SslProtocols.None; var tlsState = tlsStream.GetType().GetField("m_Worker", bindingFlags).GetValue(tlsStream); return (SslProtocols)tlsState.GetType().GetProperty("SslProtocol", bindingFlags).GetValue(tlsState); }</code>
Method 2: Use TcpClient
Alternatively, you can use the TcpClient
class to establish a TCP connection. TcpClient
also provides access to SslStream
, allowing you to check the negotiated TLS version. This method is useful if you need to determine the TLS version before initiating an HTTP request.
<code class="language-csharp">TlsInfo tlsInfo = null; IPHostEntry dnsHost = await Dns.GetHostEntryAsync(HostURI.Host); using (TcpClient client = new TcpClient(dnsHost.HostName, 443)) { using (SslStream sslStream = new SslStream(client.GetStream(), false, TlsValidationCallback, null)) { sslstream.AuthenticateAsClient(dnsHost.HostName, null, (SslProtocols)ServicePointManager.SecurityProtocol, false); tlsInfo = new TlsInfo(sslStream); } } public class TlsInfo { public TlsInfo(SslStream secStream) { this.ProtocolVersion = secStream.SslProtocol; } public SslProtocols ProtocolVersion { get; set; } }</code>
Both methods provide a way to determine the negotiated TLS version during secure HTTP communications, allowing you to make informed decisions based on your security requirements.
The above is the detailed content of How to Determine the Negotiated TLS Version in .NET Framework?. For more information, please follow other related articles on the PHP Chinese website!