So erstellen Sie SslStream für einen nicht blockierenden asynchronen Socket

Ich habe einen asynchronen system.net.socket mit mehreren Threads, der einen Port überwacht. Ich habe kein Problem, wenn ich eine Anfrage von HTTP bekomme, aber kürzlich musste ich meiner Anwendung https-Unterstützung hinzufügen.

Der Client hat mir eine .arm-Zertifizierungsdatei gegeben. Es enthält Base-64-codierte ASCII-Daten. Der Dateiname lautet cert.arm und befindet sich im Stammverzeichnis meines Lösungsordners.

Hier ist das, was ich bis jetzt mache, um dieses Zertifikat zu verwenden:

using System;
using System.Net;
using System.Threading;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace SocketExample
{
    public class StackOverFlow
    {
        public static ManualResetEvent _manualResetEvent = new ManualResetEvent(false);
        private static X509Certificate2 _cert = X509Certificate2("..\\..\\cert.arm");

        static void Main(string[] args)
        {
            StartListening();
        }

        private static void StartListening()
        {
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 9002);

            if (localEndPoint != null)
            {
                Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                if (listener != null)
                {
                    listener.Bind(localEndPoint);
                    listener.Listen(10);

                    Console.WriteLine("Socket listener is running...");

                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                }
            }
        }

        private static void AcceptCallback(IAsyncResult ar)
        {
            _manualResetEvent.Set();

            Socket listener = (Socket)ar.AsyncState;

            Socket handler = listener.EndAccept(ar);

            SslStream sslStream = new SslStream(new NetworkStream(handler, false));
            sslStream.AuthenticateAsServer(_cert); // I get exception on this line

            StateObject state = new StateObject();
            state.workSocket = handler;

            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);

            listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
        }

        private static void ReceiveCallback(IAsyncResult result)
        {
            StateObject state = (StateObject)result.AsyncState;
            Socket handler = state.workSocket;

            int numBytesReceived = handler.EndReceive(result);

            if (!handler.Connected)
            {
                handler.Close();
                return;
            }

            if (numBytesReceived > 0)
            {
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, numBytesReceived));

                string[] lines = state.sb.ToString().Split('\n');

                if (lines[lines.Length - 1] == "EOF")
                {
                    // All Data Received. Do Something.
                }
                else
                {
                    // All Data is not received. Continue reading...
                    handler.BeginReceive(state.buffer, 0, state.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
                }
            }
        }
    }
}

ie @Certification-Datei wurde erfolgreich erstellt. Ich kann die Daten in _cert Variable sehen. Es ist okay

Das Problem ist, dass beim Aufrufen der AuthenticateAsServer-Methode die NotSupportedException angezeigt wird, die besagt: "Der Servermodus SSL muss ein Zertifikat mit dem zugehörigen privaten Schlüssel verwenden."

Wie kann ich diese Zertifizierungsdatei auf meinen Socket anwenden?

Vielen Dan

Antworten auf die Frage(2)

Ihre Antwort auf die Frage