Я пытаюсь создать пример. NET Core Server Client. Но мой код не будет работать с аутентификацией клиента. Работает только с проверкой подлинности только на сервере.
Ошибка:
Ошибка SSL: RemoteCertificateNotAvailable AuthenticationException Удаленный сертификат недействителен в соответствии с процедурой проверки.!
* * * * * * * * * * * * * В моем Проводнике и реестре включено TLS13
, и сертификаты Базового примера импортированы. (но прочитано из файла, проверено с импортированным сертификатом с тем же результатом).
В чем моя вина?
Я загружаю базовый код tls1.2
из: Ссылка на базовый код
Код моего сервера
using System;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace TCP_TLS13_Server
{
class Program
{
private static readonly int ServerPort = 8433;
//private static readonly string ServerCertificateName = "MyServer";
private static readonly string ServerCertificateFile = "server.pfx";
private static readonly string ServerCertificatePassword = null;
static void Main(string[] args)
{
try
{
////read from the store (must have a key there)
//var store = new X509Store(StoreLocation.CurrentUser);
//store.Open(OpenFlags.ReadOnly);
//var serverCertificateCollection = store.Certificates.Find(X509FindType.FindBySubjectName, ServerCertificateName, false);
//var serverCertificate = serverCertificateCollection[0];
//read from the file
var serverCertificate = new X509Certificate2(ServerCertificateFile, ServerCertificatePassword);
var listener = new TcpListener(IPAddress.Any, ServerPort);
listener.Start();
Console.WriteLine("Started listening.");
while (true)
{
try
{
Console.WriteLine();
Console.WriteLine("Waiting for a client to connect...");
using (var client = listener.AcceptTcpClient())
using (var sslStream = new SslStream(client.GetStream(), false, App_CertificateValidation, null, EncryptionPolicy.RequireEncryption)) {
//using (var sslStream = new SslStream(client.GetStream())) {
Console.WriteLine("Accepted client " + client.Client.RemoteEndPoint.ToString());
sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls13, false);
Console.WriteLine("SSL authentication completed.");
Console.WriteLine("SSL using local certificate {0}.", sslStream.LocalCertificate.Subject);
if (sslStream.RemoteCertificate != null)
Console.WriteLine("SSL using remote certificate {0}.", sslStream.RemoteCertificate.Subject);
// Display the properties and settings for the authenticated stream.
DisplaySecurityLevel(sslStream);
DisplaySecurityServices(sslStream);
DisplayCertificateInformation(sslStream);
DisplayStreamProperties(sslStream);
var outputMessage = "Hello from the server.";
var outputBuffer = Encoding.UTF8.GetBytes(outputMessage);
sslStream.Write(outputBuffer);
Console.WriteLine("Sent: {0}", outputMessage);
var inputBuffer = new byte[4096];
var inputBytes = 0;
while (inputBytes == 0)
{
inputBytes = sslStream.Read(inputBuffer, 0, inputBuffer.Length);
}
var inputMessage = Encoding.UTF8.GetString(inputBuffer, 0, inputBytes);
Console.WriteLine("Received: {0}", inputMessage);
}
}
catch (Exception ex)
{
Console.WriteLine("*** {0}\n*** {1}!", ex.GetType().Name, ex.Message);
}
}
}
catch (Exception ex)
{
Console.WriteLine("*** {0}\n*** {1}!", ex.GetType().Name, ex.Message);
}
Console.WriteLine();
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
private static bool App_CertificateValidation(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None) { return true; }
if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors) { return true; } //we don't have a proper certificate tree
Console.WriteLine("*** SSL Error: " + sslPolicyErrors.ToString());
return false;
}
static void DisplaySecurityLevel(SslStream stream)
{
Console.WriteLine("Cipher: {0} strength {1}", stream.CipherAlgorithm, stream.CipherStrength);
Console.WriteLine("Hash: {0} strength {1}", stream.HashAlgorithm, stream.HashStrength);
Console.WriteLine("Key exchange: {0} strength {1}", stream.KeyExchangeAlgorithm, stream.KeyExchangeStrength);
Console.WriteLine("Protocol: {0}", stream.SslProtocol);
}
static void DisplaySecurityServices(SslStream stream)
{
Console.WriteLine("Is authenticated: {0} as server? {1}", stream.IsAuthenticated, stream.IsServer);
Console.WriteLine("IsSigned: {0}", stream.IsSigned);
Console.WriteLine("Is Encrypted: {0}", stream.IsEncrypted);
}
static void DisplayStreamProperties(SslStream stream)
{
Console.WriteLine("Can read: {0}, write {1}", stream.CanRead, stream.CanWrite);
Console.WriteLine("Can timeout: {0}", stream.CanTimeout);
}
static void DisplayCertificateInformation(SslStream stream)
{
Console.WriteLine("Certificate revocation list checked: {0}", stream.CheckCertRevocationStatus);
X509Certificate localCertificate = stream.LocalCertificate;
if (stream.LocalCertificate != null)
{
Console.WriteLine("Local cert was issued to {0} and is valid from {1} until {2}.",
localCertificate.Subject,
localCertificate.GetEffectiveDateString(),
localCertificate.GetExpirationDateString());
}
else
{
Console.WriteLine("Local certificate is null.");
}
// Display the properties of the client's certificate.
X509Certificate remoteCertificate = stream.RemoteCertificate;
if (stream.RemoteCertificate != null)
{
Console.WriteLine("Remote cert was issued to {0} and is valid from {1} until {2}.",
remoteCertificate.Subject,
remoteCertificate.GetEffectiveDateString(),
remoteCertificate.GetExpirationDateString());
}
else
{
Console.WriteLine("Remote certificate is null.");
}
}
}
}
Мой клиент
using System;
using System.Diagnostics;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace TCP_TLS13_Client
{
class Program
{
private static readonly string ServerHostName = "localhost";
private static readonly int ServerPort = 8433;
//private static readonly string ServerHostName = "google.com";
//private static readonly int ServerPort = 433;
private static readonly string ServerCertificateName = "MyServer";
private static readonly string ClientCertificateName = "MyClient";
private static readonly string ClientCertificateFile = "client.pfx";
private static readonly string ClientCertificatePassword = null;
static void Main(string[] args)
{
try
{
////read from the store (must have a key there)
//var store = new X509Store(StoreLocation.CurrentUser);
//store.Open(OpenFlags.ReadOnly);
//var clientCertificateCollection = store.Certificates.Find(X509FindType.FindBySubjectName, ClientCertificateName, false);
//read from the file
var clientCertificate = new X509Certificate2(ClientCertificateFile, ClientCertificatePassword);
var clientCertificateCollection = new X509CertificateCollection(new X509Certificate[] { clientCertificate });
using (var client = new TcpClient(ServerHostName, ServerPort))
using (var sslStream = new SslStream(client.GetStream(), false, App_CertificateValidation, LocalCertificateSelectionCallback, EncryptionPolicy.RequireEncryption))
{
// Ensure the client does not close when there is still data to be sent to the server.
client.LingerState = (new LingerOption(true, 0));
Console.WriteLine("Client connected.");
sslStream.AuthenticateAsClient(ServerCertificateName, clientCertificateCollection, SslProtocols.Tls13, false); //For Server and Client auth
//IPAddress IP = ((IPEndPoint)client.Client.RemoteEndPoint).Address;
//sslStream.AuthenticateAsClient(ServerCertificateName, null, SslProtocols.Tls13, false); //For Server auth
Console.WriteLine("SSL authentication completed.");
if (sslStream.LocalCertificate != null)
Console.WriteLine("SSL using local certificate {0}.", sslStream.LocalCertificate.Subject);
Console.WriteLine("SSL using remote certificate {0}.", sslStream.RemoteCertificate.Subject);
var outputMessage = "Hello from the client " + Process.GetCurrentProcess().Id.ToString() + ".";
var outputBuffer = Encoding.UTF8.GetBytes(outputMessage);
sslStream.Write(outputBuffer);
Console.WriteLine("Sent: {0}", outputMessage);
var inputBuffer = new byte[4096];
var inputBytes = 0;
while (inputBytes == 0)
{
inputBytes = sslStream.Read(inputBuffer, 0, inputBuffer.Length);
}
var inputMessage = Encoding.UTF8.GetString(inputBuffer, 0, inputBytes);
Console.WriteLine("Received: {0}", inputMessage);
}
}
catch (Exception ex)
{
Console.WriteLine("*** {0}\n*** {1}!", ex.GetType().Name, ex.Message);
}
Console.WriteLine();
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
public static X509Certificate LocalCertificateSelectionCallback(object sender, string targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers)
{
return localCertificates[0];
}
private static bool App_CertificateValidation(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None) { return true; }
if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors) { return true; } //we don't have a proper certificate tree
Console.WriteLine("*** SSL Error: " + sslPolicyErrors.ToString());
return false;
}
}
}