如何为非阻塞异步套接字创建SslStream [英] How to Create SslStream for a non-blocking async socket
问题描述
我有一个侦听端口的多线程异步 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屋!