如何为非阻塞异步套接字创建SslStream [英] How to Create SslStream for a non-blocking async socket

查看:45
本文介绍了如何为非阻塞异步套接字创建SslStream的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个侦听端口的多线程异步 System.Net.Socket .如果我收到来自HTTP的请求,我没有任何问题,但是最近我不得不在应用程序中添加https支持.

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

这是我到目前为止要使用该证书的步骤:

 使用系统;使用System.Net;使用System.Threading;使用System.Net.Security;使用System.Net.Sockets;使用System.Security.Cryptography.X509Certificates;使用System.Text;命名空间SocketExample{公共类StackOverFlow{公共静态ManualResetEvent _manualResetEvent =新的ManualResetEvent(false);私有静态X509Certificate2 _cert = X509Certificate2(".. \\ .. \\ cert.arm");静态void Main(string [] args){StartListening();}私有静态无效StartListening(){IPEndPoint localEndPoint =新的IPEndPoint(IPAddress.Any,9002);如果(localEndPoint!= null){套接字侦听器=新的Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);如果(侦听器!= null){listener.Bind(localEndPoint);listener.Listen(10);Console.WriteLine(套接字侦听器正在运行...");listener.BeginAccept(new AsyncCallback(AcceptCallback),监听器);}}}私有静态无效AcceptCallback(IAsyncResult ar){_manualResetEvent.Set();套接字侦听器=(Socket)ar.AsyncState;套接字处理程序= listener.EndAccept(ar);SslStream sslStream =新的SslStream(新的NetworkStream(处理程序,假));sslStream.AuthenticateAsServer(_cert);//我在这一行上遇到异常StateObject状态=新的StateObject();state.workSocket =处理程序;handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,new AsyncCallback(ReceiveCallback),state);listener.BeginAccept(new AsyncCallback(AcceptCallback),监听器);}私有静态无效ReceiveCallback(IAsyncResult结果){StateObject状态=(StateObject)result.AsyncState;套接字处理程序= state.workSocket;int numBytesReceived = handler.EndReceive(result);如果(!handler.Connected){handler.Close();返回;}如果(numBytesReceived> 0){state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,numBytesReceived));string [] lines = state.sb.ToString().Split('\ n');如果(lines [lines.Length-1] =="EOF"){//接收到所有数据.做一点事.}别的{//未收到所有数据.继续阅读...handler.BeginReceive(state.buffer,0,state.buffer.Length,SocketFlags.None,新的AsyncCallback(ReceiveCallback),state);}}}}} 

证书文件已成功创建.我可以在_cert变量中看到数据.没关系.

问题是,当我调用 AuthenticateAsServer 方法时,我得到 NotSupportedException ,它说:服务器模式SSL必须使用带有关联私钥的证书"./p>

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

解决方案

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

X509Certificate 不同,

X509Certificate2 具有私钥的成员,并且SSL套接字需要私钥来完成其工作.

I have a multi threaded async System.Net.Socket which listens on a port. I don't have any problem if I get a request from HTTP, but recently I had to add https support to my application.

The client gave me an .arm certification file. It has base-64 encoded ASCII data in it. The file name is cert.arm and it is stored in the root of my solution folder.

Here is what I do till now to use that certificate:

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

Certification file is created successfully. I can see the data in _cert variable. It is OK.

The problem is that when I call the AuthenticateAsServer method I get NotSupportedException which says: "The server mode SSL must use a certificate with the associated private key".

How can I apply this certification file to my socket?

解决方案

You should probably use X509Certificate2 instead of X509Certificate. It could be the only step required to resolve this error.

X509Certificate2 has a member for the private key, unlike X509Certificate, and the SSL socket needs the private key to do its job.

这篇关于如何为非阻塞异步套接字创建SslStream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆