带有客户端身份验证的.NET Core TLS1.3服务器-客户端示例

时间:2020-02-14 18:43:14

标签: .net ssl console

我探究创建一个.NET Core Server Client示例。但是我的代码不适用于客户端身份验证。仅适用于仅服务器身份验证。

错误:

SSL错误:RemoteCertificateNotAvailable AuthenticationException 根据验证步骤,远程证书无效。!

TLS13已在我的资源管理器和注册表中启用,并且导入了基本示例证书。 (但从文件中读取,并使用导入的证书进行测试,结果相同)。

我怎么了?

我从以下位置下载tls1.2基本代码: Base Code link

我的服务器代码

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;
    }
}
}

0 个答案:

没有答案