HTTPS证书创建+绑定端口+C#程序监听

//用C#的exe程序,搭建HTTPS监听,可用于静态网站、接口、模拟WebApi等等
//由于是客户端EXE,可以正常访问客户端所有硬件资源
//如:web界面上调用http://localhost:xx/+参数,调用本地硬件、本地缓存(内存或文件,可代替cookies)、打开本地程序、调用打印机、扫码墩…

C#的HTTPListen本身就能实现以上功能,本文主要讲述利用证书,将HTTP升级到HTTPS

1. 下载OpenSSL

http://slproweb.com/download/Win64OpenSSL-1_1_1c.exe

2. 安装OpenSSL

3. 使用OpenSSL创建证书:

4. 创建私有CA,然后用该CA给证书进行签名

win+r, cmd, cd C:\Program Files\OpenSSL-Win64\bin

4.1 创建CA私钥

 openssl genrsa -des3 -out ca.key 4096

设置CA密码

4.2 生成CA的自签名证书,其实CA证书就是一个自签名证书

openssl req -new -x509 -days 36500 -keyca.key -out ca.crt

输入CA密码

 Country Name (2 letter code) [AU]:CN            --国家
 State or Province Name (full name) [Some-State]:XH        --地区
 Locality Name (eg, city) []:SH             --城市
 Organization Name (eg, company) [Internet Widgits Pty Ltd]:公司名称
 Organizational Unit Name (eg, section) []:部门名称
 Common Name (e.g. server FQDN or YOUR name) []:域名/IP
 Email Address []:

-days 为证书有效期(单位:天)

4.3.生成客户端证书私钥

openssl genrsa -des3 -out localhost.key 4096

设置客户端证书密码

4.4.需要签名的对象(服务端)生成证书签名请求

openssl req -new -key localhost.key -out localhost.csr

输入客户端证书密码

Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:CN
Locality Name (eg, city) []:CN
Organization Name (eg, company) [Internet Widgits Pty Ltd]:xxx           --组织名称
Organizational Unit Name (eg, section) []:xxx                        --单位、部门,可同组织名称
Common Name (e.g. server FQDN or YOUR name) []:localhost                    --很关键,必须是url中的ip地址/或域名
Email Address []:

Please enter the following 'extra' attributes 
to be sent with your certificate request   -- 一些额外的信息
A challenge password []: xxx                       --证书交换密码(可省略)
An optional company name []:xx                     --公司名称(可省略)

这里注意证书签名请求当中的Common Name很关键,必须是url中的ip地址/或域名

4.5.用步骤4.2创建的CA证书给步骤4.4生成的签名请求进行签名

openssl x509 -req -days 365 -in localhost.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out localhost.crt

输入CA密码
-days 为证书有效期(单位:天)

4.6.合成 pfx

openssl pkcs12 -export -out localhost.pfx -inkey localhost.key -in localhost.crt

设置密码:证书安装密码

5.使用:

5.1 安装证书,双击pfx文件,安装到:“本地计算机”–>“个人
5.2 双击打开crt证书,详细信息中可以看到“指纹”(certhash)
5.3 执行端口绑定(默认443端口)

netsh http add sslcert ipport=0.0.0.0:8000 certhash=指纹 appid={程序GUID/newguid} clientcertnegotiation=enable

如:

netsh http add sslcert ipport=0.0.0.0:8000 certhash=0000000000003ed9cd0c315bbb6dc1c08da5e6 appid={00112233-4455-6677-8899-AABBCCDDEEFF} clientcertnegotiation=enable

【HTTPListen】

using System;
public class test
{
    public test()
    {
        System.Net.HttpListener httpListener = new System.Net.HttpListener();
        httpListener.AuthenticationSchemes =  System.Net.AuthenticationSchemes.Anonymous;
        httpListener.Prefixes.Add("https://*:8000/"); // 支持http (不使用证书)
        httpListener.Start();
        new System.Threading.Thread(new System.Threading.ThreadStart(delegate
        {
            while (true)
            {
                try
                {
                    System.Net.HttpListenerContext httpListenerContext =  httpListener.GetContext();
                    new System.Threading.Thread(new  System.Threading.ParameterizedThreadStart((input) =>
                    {
                        System.Net.HttpListenerContext ctx =  (System.Net.HttpListenerContext)input;
                        System.Net.HttpListenerRequest request = ctx.Request;
                        string pram = request.QueryString["Data"];//Get入参
                        string responseMessage = string.Empty;//返回值
                        if (!string.IsNullOrEmpty(pram))
                        {
                            //Get入参,url解 码
                            pramOrg = pram;
                            pram = System.Web.HttpUtility.UrlDecode(pram);
                        }
                        //POST入参
                        if (request.HttpMethod == "POST")
                        {
                            //处理业务请求
                            StreamReader reader = new  StreamReader(request.InputStream, Encoding.UTF8);
                            pram = reader.ReadToEnd();
                            reader.Close();
                            reader.Dispose();
                        }
                        #region 业务处理
                        try
                        {
                            //业务处理
                            responseMessage = "业务结果";
                        }
                        catch (Exception ex)
                        {
                            //异常处理
                            responseMessage = ex.Message;
                        }
                        #endregion 业务处理
                        #region 返回给调用者
                        //输出类型
                        httpListenerContext.Response.ContentType = "text/html;  charset=UTF-8";
                        //返回状态
                        httpListenerContext.Response.StatusCode = 200;
                        //设置授权,尝试解决Jquery跨域问题
                         //httpListenerContext.Response.Headers["Access-Control-Allow-Origin"] = "*";
                         //httpListenerContext.Response.Headers["Access-Control-Allow-Methods"] =  "GET,POST";
                         //httpListenerContext.Response.Headers["Access-Control-Max-Age"] = "1000";
                        try
                        {
                            //输出界面内容
                            if (!string.IsNullOrEmpty(responseMessage))
                            {
                                //返回文本内容
                                using (StreamWriter writer = new  StreamWriter(httpListenerContext.Response.OutputStream))
                                {
                                    writer.Write(responseMessage);
                                }
                            }
                        }
                        catch
                        {
                            //刷新太快异常,不做处理
                        }
                        #endregion 返回给调用者
                    })).Start(httpListenerContext);
                }
                catch
                { }
            }
        })).Start();
    }
}
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
是的,C#可以同时监听多个UDP端口并接收数据。你可以创建多个UdpClient对象来监听不同的端口,并使用异步接收方法BeginReceive和EndReceive来接收数据。以下是一个简单的示例代码: ``` using System; using System.Net; using System.Net.Sockets; class Program { static void Main(string[] args) { // 监听端口列表 int[] ports = { 1234, 5678, 9012 }; // 创建多个UdpClient对象并绑定到不同的端口 UdpClient[] clients = new UdpClient[ports.Length]; for (int i = 0; i < ports.Length; i++) { clients[i] = new UdpClient(ports[i]); } Console.WriteLine("正在监听端口:{0}", string.Join(", ", ports)); // 异步接收数据 foreach (UdpClient client in clients) { client.BeginReceive(new AsyncCallback(ReceiveCallback), client); } Console.ReadLine(); } static void ReceiveCallback(IAsyncResult ar) { UdpClient client = (UdpClient)ar.AsyncState; IPEndPoint remoteEP = null; byte[] data = client.EndReceive(ar, ref remoteEP); Console.WriteLine("收到来自 {0} 的数据:{1}", remoteEP, Encoding.UTF8.GetString(data)); // 继续异步接收数据 client.BeginReceive(new AsyncCallback(ReceiveCallback), client); } } ``` 在这个例子中,我们创建了一个包含三个UDP端口的列表,并使用循环创建了三个UdpClient对象来监听这三个端口。然后,我们使用异步接收方法BeginReceive和EndReceive来接收数据,并在回调方法ReceiveCallback中处理接收到的数据。在回调方法中,我们继续异步接收数据以便能够持续监听多个端口

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值