Как использовать HTTPS для сетевой службы на C# через TcpClient, TcpListener?
По дате
По Рейтингу
Чтобы использовать HTTPS (TLS/SSL) поверх TcpClient и TcpListener в C#, тебе нужно обернуть сетевые потоки в SslStream, который предоставляет шифрование и аутентификацию. HTTPS — это просто HTTP, работающий поверх TLS, и ты сам реализуешь его "вручную" через SslStream.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
class HttpsServer
{
public static async Task StartServer(string certPath, string certPassword)
{
var certificate = new X509Certificate2(certPath, certPassword);
var listener = new TcpListener(IPAddress.Any, 4433);
listener.Start();
Console.WriteLine("HTTPS сервер запущен на порту 4433...");
while (true)
{
TcpClient client = await listener.AcceptTcpClientAsync();
_ = HandleClient(client, certificate); // fire-and-forget
}
}
private static async Task HandleClient(TcpClient client, X509Certificate2 certificate)
{
using var stream = client.GetStream();
using var sslStream = new SslStream(stream, false);
try
{
await sslStream.AuthenticateAsServerAsync(certificate, clientCertificateRequired: false, checkCertificateRevocation: false);
using var reader = new StreamReader(sslStream, Encoding.UTF8);
using var writer = new StreamWriter(sslStream, Encoding.UTF8) { AutoFlush = true };
string requestLine = await reader.ReadLineAsync();
Console.WriteLine("Получен запрос: " + requestLine);
// Простой HTTP-ответ
string response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 5\r\n\r\nHello";
await writer.WriteAsync(response);
}
catch (Exception ex)
{
Console.WriteLine("Ошибка: " + ex.Message);
}
finally
{
client.Close();
}
}
}
123456789101112131415161718192021222324252627282930313233343536373839404142
using System;
using System.IO;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
class HttpsClient
{
public static async Task ConnectToServer(string host, int port)
{
var client = new TcpClient();
await client.ConnectAsync(host, port);
using var stream = client.GetStream();
using var sslStream = new SslStream(stream, false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
await sslStream.AuthenticateAsClientAsync(host);
using var writer = new StreamWriter(sslStream, Encoding.UTF8) { AutoFlush = true };
using var reader = new StreamReader(sslStream, Encoding.UTF8);
await writer.WriteLineAsync("GET / HTTP/1.1");
await writer.WriteLineAsync($"Host: {host}");
await writer.WriteLineAsync("Connection: close");
await writer.WriteLineAsync(); // пустая строка — конец заголовков
string line;
while ((line = await reader.ReadLineAsync()) != null)
{
Console.WriteLine(line);
}
}
private static bool ValidateServerCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors)
{
// В продакшне нужно строго проверять ошибки
return true; // всегда "доверять" для тестов
}
}
Ну и к ответу Редисыча хочу добавить, что желательно все же прочитать что-нибудь умное про криптографию вообще и TLS/SSL в частности (глубоко копать не надо, но хотя бы общее представление поиметь таки надо), а также узнать про систему сертификации ключей, создания ключей, их подписи, установку и уровни доверия.