Я пытаюсь настроить простой веб-сервер HTTPS, используя TcpClient, SslStream и самозаверяющий сертификат.
Код запускается нормально, отображается ожидание клиента, но когда я подключаюсь к нему через веб-браузер, я получаю
"Сбой вызова SSPI, Клиент и сервер не могут связаться, поскольку они не обладают общим алгоритмом "
Из того, что я прочитал, это обычно означает, что сервер пытается использовать тип протокола, который клиент не имеет или не может использовать (IE: устаревший), и многие говорят, чтобы убедиться, что и сервер, и клиент используют TLS 1.2.
- я включил "ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12"
для принудительного запуска tls1.2, и я использую Firefox (и другие), которыйЯ проверил, что они в курсе и работают с tls12.
-Я на .net 4.7, так что это не должно быть проблемой, я не думаю.
-Я вручную импортировал сертификат в Firefox.
-Я попытался разрешить все протоколы без протоколов, и «по умолчанию»
-Я зашел в реестр и включил все TLS, и отключил все, кроме tls1.2, оба стот же результат.
Я уверен, что на этот вопрос уже отвечали раньше, но я уже пару дней обыскиваю SO и Google, так что я сдаюсь, жарится!
static X509CertificateserverCertificate = null;
public static int Main(string[] args)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; //Force tls 1.2
MakeCert(); //Create self signed certificate and assign to serverCertificate
SslTcpServer.RunServer();
return 0;
}
static void MakeCert()
{
var ecdsa = ECDsa.Create(); // generate asymmetric key pair
var req = new CertificateRequest("cn=localhost", ecdsa, HashAlgorithmName.SHA256);
var cert = req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddYears(5));
// Create PFX (PKCS #12) with private key
string pfxPath = Path.Combine(Environment.CurrentDirectory, "mycert.pfx");
File.WriteAllBytes(pfxPath, cert.Export(X509ContentType.Pfx, "Password"));
// Create Base 64 encoded CER (public key only)
string cerPath = Path.Combine(Environment.CurrentDirectory, "mycert.cer");
File.WriteAllText(cerPath,
"-----BEGIN CERTIFICATE-----\r\n"
+ Convert.ToBase64String(cert.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks)
+ "\r\n-----END CERTIFICATE-----");
string keyfilename = "mycert.pfx";
string certpath = Path.Combine(Environment.CurrentDirectory, keyfilename);
X509Certificate certificate = new X509Certificate2(certpath, "Password");
serverCertificate = certificate;
}
public static void RunServer()
{
TcpListener listener = new TcpListener(IPAddress.Any, 8080);
listener.Start();
while (true)
{
Console.WriteLine("Waiting for a client to connect...");
TcpClient client = listener.AcceptTcpClient();
ProcessClient(client);
}
}
static void ProcessClient(TcpClient client)
{
SslStream sslStream = new SslStream(client.GetStream(), false);
try
{
sslStream.AuthenticateAsServer(serverCertificate, clientCertificateRequired: false, enabledSslProtocols : SslProtocols.Tls12, checkCertificateRevocation: false);
Console.WriteLine("Authenticated");
}
catch (AuthenticationException e)
{
Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
Console.WriteLine("Authentication failed - closing the connection.");
sslStream.Close();
client.Close();
return;
}
finally
{
sslStream.Close();
client.Close();
}
}
Код никогда не достигает "Authenticated", всегда выдает исключение
"Ошибка вызова SSPI, см. внутреннее исключение"
с внутренним исключением
"Клиент и сервер не могут обмениваться данными, поскольку они не имеют общего алгоритма"