如何为非阻塞异步套接字创建 SslStream

Ork*_*kar 5 c# sockets

我有一个多线程异步System.Net.Socket,它侦听端口。如果我收到来自 HTTP 的请求,我不会遇到任何问题,但最近我必须向我的应用程序添加 https 支持。

客户给了我一份.arm认证文件。它包含 base-64 编码的 ASCII 数据。文件名是cert.arm,它存储在我的解决方案文件夹的根目录中。

到目前为止,我使用该证书的操作如下:

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);
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

认证文件创建成功。我可以看到 _cert 变量中的数据。没关系。

问题是,当我调用该AuthenticateAsServer方法时,我得到NotSupportedException的信息是:“服务器模式 SSL 必须使用带有关联私钥的证书”。

如何将此认证文件应用到我的套接字?

Rom*_*kov 2

您可能应该使用X509Certificate2而不是X509Certificate. 这可能是解决此错误所需的唯一步骤。

X509Certificate2与 不同的是,有一个私钥成员X509Certificate,并且 SSL 套接字需要私钥才能完成其工作。