This method performs the SSL/TLS handshake for an SslStream. It negotiates the SSL/TLS protocol version, cipher suite, and other security parameters between the client and server. This is a crucial step in establishing a secure communication channel.
public void Negotiate(
int millisecondsTimeout
)
| Name | Description |
|---|---|
millisecondsTimeout |
The time-out value, in milliseconds, for the Negotiate operation. A value of 0 specifies an infinite time-out. |
The Negotiate method initiates the SSL/TLS handshake process. This process involves exchanging security parameters and establishing an encrypted session. The method blocks until the handshake is complete or the specified time-out is reached.
It is important to set an appropriate time-out value to prevent the application from hanging indefinitely if the handshake fails or takes too long.
This method can throw exceptions if the handshake fails due to reasons such as:
SslStream.AuthenticateAsClient, and for server applications, you call SslStream.AuthenticateAsServer. The Negotiate method is a lower-level operation and is often called internally by the authentication methods.
using System;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
public class SslExample
{
public static async Task PerformSslNegotiation(TcpClient tcpClient, string targetHost)
{
SslStream sslStream = null;
try
{
sslStream = new SslStream(
tcpClient.GetStream(),
false,
new RemoteCertificateValidationCallback(ValidateServerCertificate),
null
);
// Set a time-out of 30 seconds for the negotiation
int timeoutMilliseconds = 30000;
Console.WriteLine($"Starting SSL/TLS negotiation with timeout: {timeoutMilliseconds}ms...");
await Task.Run(() => sslStream.Negotiate(timeoutMilliseconds)); // Blocking call, run in task for responsiveness
Console.WriteLine("SSL/TLS negotiation successful.");
// Now you can use sslStream for encrypted communication
// For example: await sslStream.WriteAsync(data);
// await sslStream.ReadAsync(buffer);
}
catch (Exception ex)
{
Console.WriteLine($"SSL/TLS negotiation failed: {ex.Message}");
}
finally
{
// Clean up resources
sslStream?.Dispose();
tcpClient.Close();
}
}
// Callback to validate the server certificate (for client-side)
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true; // Certificate is valid
}
Console.WriteLine($"Certificate error: {sslPolicyErrors}");
// For development/testing, you might accept invalid certificates,
// but this is NOT recommended for production.
// return true;
return false; // Reject the certificate
}
// Example usage (would be part of a larger client/server application)
public static async Task Main(string[] args)
{
// This is a placeholder. In a real scenario, you'd establish a TcpClient connection first.
// For demonstration, we'll simulate an error scenario.
Console.WriteLine("Simulating SSL negotiation (no actual connection established in this snippet).");
// TcpClient client = new TcpClient();
// try {
// await client.ConnectAsync("example.com", 443);
// await PerformSslNegotiation(client, "example.com");
// } catch (Exception e) {
// Console.WriteLine($"Error connecting or negotiating: {e.Message}");
// }
}
}
| Assembly | Package |
|---|---|
| System.Net.Primitives.dll | Microsoft.NETCore.App (if using .NET Core/5+) |
| System.dll | Microsoft.NETFramework.ReferenceAssemblies.net4x (if using .NET Framework) |