没有客户端证书的C#TLS客户端

时间:2019-06-11 08:58:12

标签: c# sockets ssl tls1.2

我正在尝试创建TLS client TLS不需要的client certificate

这可用于client certificate

using System;
using System.Diagnostics;
using System.Globalization;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace SslClient {
    class App {

        private static readonly string ServerIpAddress = "127.0.0.1";
        private static readonly int ServerPort = 3000;
        private static readonly string ServerCertificateName = "MyServer";

        private static readonly string ClientCertificateFile = "client.pfx";
        private static readonly string ClientCertificatePassword = null;


        static void Main(string[] args) {
            try {
                var clientCertificate = new X509Certificate2(ClientCertificateFile, ClientCertificatePassword);
                var clientCertificateCollection = new X509CertificateCollection(new X509Certificate[] { clientCertificate });

                using (var client = new TcpClient(ServerIpAddress, ServerPort))
                using (var sslStream = new SslStream(client.GetStream(), false, App_CertificateValidation)) {
                    Console.WriteLine("Device connected.");

                    sslStream.AuthenticateAsClient(ServerCertificateName, clientCertificateCollection, SslProtocols.Tls12, false);

                    var outputMessage = "Hello";
                    var outputBuffer = Encoding.UTF8.GetBytes(outputMessage);
                    sslStream.Write(outputBuffer);

                    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(inputMessage);
                }
            } catch (Exception ex) {
                Console.WriteLine("***** {0}\n***** {1}!", ex.GetType().Name, ex.Message);
            }
        }


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

尝试消除对TLS client certificate的需求如下:

using System;
using System.Diagnostics;
using System.Globalization;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace SslClient {
    class App {

        private static readonly string ServerIpAddress = "127.0.0.1";
        private static readonly int ServerPort = 3000;

        static void Main(string[] args) {
            try {
                using (var client = new TcpClient(ServerIpAddress, ServerPort))
                using (var sslStream = new SslStream(client.GetStream(), false)) {
                    Console.WriteLine("Device connected.");

                    var outputMessage = "Hello";
                    var outputBuffer = Encoding.UTF8.GetBytes(outputMessage);

                    try {
                        sslStream.Write(outputBuffer);
                    } catch (Exception x) {
                        var baseException = x.GetBaseException();
                        Console.WriteLine(baseException);
                    }


                    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(inputMessage);
                }
            } catch (Exception ex) {
                Console.WriteLine("***** {0}\n***** {1}!", ex.GetType().Name, ex.Message);
            }
        }

    }
}

但这输出:

Device connected.
System.InvalidOperationException: This operation is only allowed using a successfully authenticated context.
  at Mono.Net.Security.MobileAuthenticatedStream.CheckThrow (System.Boolean authSuccessCheck, System.Boolean shutdownCheck) [0x0001e] in <cbad0c8bbe7b432eb83038c06be00093>:0
  at Mono.Net.Security.MobileAuthenticatedStream+<StartOperation>d__58.MoveNext () [0x00011] in <cbad0c8bbe7b432eb83038c06be00093>:0
***** AggregateException
***** One or more errors occurred.!

1 个答案:

答案 0 :(得分:0)

如果使用tls,则需要更改代码,首先需要进行身份验证。

using System;
using System.Diagnostics;
using System.Globalization;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace SslClient {
class App {

    private static readonly string ServerIpAddress = "127.0.0.1";
    private static readonly int ServerPort = 3000;

    static void Main(string[] args) {
        try {
            using (var client = new TcpClient(ServerIpAddress, ServerPort))
            using (var sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(App_CertificateValidation)) {
            sslStream.AuthenticateAsClient(ServerIpAddress);
                Console.WriteLine("Device connected.");

                var outputMessage = "Hello";
                var outputBuffer = Encoding.UTF8.GetBytes(outputMessage);

                try {
                    sslStream.Write(outputBuffer);
                } catch (Exception x) {
                    var baseException = x.GetBaseException();
                    Console.WriteLine(baseException);
                }


                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(inputMessage);
            }
        } catch (Exception ex) {
            Console.WriteLine("***** {0}\n***** {1}!", ex.GetType().Name, ex.Message);
        }
    }
 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;
    }
}
}