c# SSL TCPServer 卡在 SsLStream.AuthenticateAsServer()

2024-03-25

故事情节:

我想用 C# 创建我自己的网络服务器(第一次尝试)。进展顺利(我正在使用Visual Studio 到代码申请和火狐浏览器检查如果我做得对的话)并且我成功地制作了一个基本的 TCPServer。当我尝试向其添加 SSL 支持时,遇到了问题。

  • 在过去 7 天里,我一直在尝试使用 SSLStream.AuthenticateAsServer([自签名证书]) 作为具有 SSL 支持的 TcpServer 进行身份验证

Problem:

当我从我心爱的 Firefox 收到 [Upgrade-Insecure-Requests: 1] 时,我正在尝试 [SSLStream.AuthenticateAsServer([自签名证书])]。这样做我的代码被卡住了(但不会冻结/崩溃)在这一行同时我的 Firefox 一直在加载似乎没有给我发送回复。

Code:


starting my server
TCPServer.ServerStart(8080);

(listener is being defined in my TCPServer class)
internal static TcpListener listener;

async internal static void ServerStart(int port)
    {
        if (listener == null)
        {
            listener = new TcpListener(IPAddress.Any, port);
        }
        listener.Start();

        //clients
        await Task.Run(()=> SucheNachBesuchern());
        listener.Stop();
    }

accepting clients
private static void SucheNachBesuchern(){
        TcpClient Besucher;

        while (true)
        {
            Besucher = listener.AcceptTcpClient();
            ThreadPool.QueueUserWorkItem(ThreadProzess, Besucher);
        }
    }

handling accepted clients
private static void ThreadProzess(object Besucher) {
        TcpClient besucher = (TcpClient)Besucher;
        Abfertige(besucher);
        besucher.Close();
        besucher.Dispose();
    }

private static void Abfertige(TcpClient Besucher)
    {
        //Reading the Request
        StreamReader Auftrag = new StreamReader(Besucher.GetStream());
        List<String> AuftragNachricht= new List<String>();
        while (Auftrag.Peek()!=-1) {
            AuftragNachricht.Add(Auftrag.ReadLine());
        }

        //Anfrage = request Class with bool Anfrage.SSLAnfrage being true
        //if the request contains 'Upgrade-Insecure-Requests: 1'
        Anfrage Anfrage = Anfrage.VerarbeiteAuftrag(AuftragNachricht);

        if (Anfrage.SSLAnfrage)// = if([request conatined 'Upgrade-Insecure-Requests: 1'])
        {
            //opening an SslStream to the TcpClient Besucher
            SslStream SSLStream = new SslStream(Besucher.GetStream(), false);
            try
            {
                //Authenticating as TcpServer supporting SSL !CODE IS STUCK AT THIS LINE!
                SSLStream.AuthenticateAsServer([SELFSINGEDX509CERTIFICATE.cer using openssl pkcs12], clientCertificateRequired: false, enabledSslProtocols: System.Security.Authentication.SslProtocols.Default, checkCertificateRevocation: false);

                //set timeouts for read and write
                SSLStream.ReadTimeout = 5000;
                SSLStream.WriteTimeout = 5000;

                //tryig to catch my Firefox as new client on SSL port 443
                TcpListener SSLListener = new TcpListener(IPAddress.Parse("192.168.178.72"), 443); 
                SSLListener.Start();
                TcpClient SSLBesucher = SSLListener.AcceptTcpClient();
                Debug.WriteLine("I'VE GOT A CLIENT HERE!!!!111");
            }
            catch (Exception Error) {
                Debug.WriteLine($"---Error gefangen: {Error.ToString()}");
            }
        }//[...more Code]

(For not having any knowledge in SSL I used this example-code https://learn.microsoft.com/en-us/dotnet/api/system.net.security.sslstream?view=netframework-4.7.2)

我做到了!问题是(在我的线程中)我使用的是 X509Certificate 公共证书,其中没有密钥,而不是 X509Certificate2 私有证书,其中有密钥。这就是为什么我的代码在 SslStream.AuthenticateAsServer(); 处挂起。@瓦西里·法罗诺夫 https://stackoverflow.com/users/200445/vasiliy-faronov答案也确实对我很有帮助(我需要向端口 443 添加 307 标头),谢谢。

无论如何,这里是一个如何通过 tcp 级别的 https 发送 index.html 到您的网络浏览器的示例:

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace SSLTEST
{
    class Program
    {
        static X509Certificate2 CER = new X509Certificate2("privatecert.cer","pass");// Has to be a private X509cert with key
        static void Main(string[] args)
        {
            TcpListener listener = new TcpListener(IPAddress.Parse("192.168.178.72"), 443);
            listener.Start();
            TcpClient client = listener.AcceptTcpClient();
            Console.WriteLine("client accepted");

            SslStream stream = new SslStream(client.GetStream());
            stream.AuthenticateAsServer(CER, false, System.Security.Authentication.SslProtocols.Tls12, false);
            Console.WriteLine("server authenticated");


            Console.WriteLine("----client request----");
            Decoder decoder = Encoding.UTF8.GetDecoder();
            StringBuilder request = new StringBuilder();
            byte[] buffer = new byte[2048];
            int bytes = stream.Read(buffer, 0, buffer.Length);

            char[] chars = new char[decoder.GetCharCount(buffer, 0, buffer.Length)];
            decoder.GetChars(buffer, 0, bytes, chars, 0);

            request.Append(chars);

            Console.WriteLine(request.ToString());
            Console.WriteLine("---------------------");

            String method = request.ToString().Split('\n')[0].Split(' ')[0];
            String requestedfile = request.ToString().Split('\n')[0].Split(' ')[1];
            if (method == "GET" & requestedfile == "/")
            {
                FileStream datastream = new FileInfo(Environment.CurrentDirectory+@"\"+"index.html").OpenRead();
                BinaryReader datareader = new BinaryReader(datastream);
                byte[] data = new byte[datastream.Length];
                datastream.Read(data, 0, data.Length);
                datastream.Close();

                StringBuilder header = new StringBuilder();
                header.AppendLine("HTTP/1.1 200 OK");
                header.AppendLine("Content-Length: "+data.Length);
                header.AppendLine();

                List<Byte> responsedata = new List<byte>();
                responsedata.AddRange(Encoding.ASCII.GetBytes(header.ToString()));
                responsedata.AddRange(data);

                stream.Write(responsedata.ToArray(), 0, responsedata.ToArray().Length);
                Console.WriteLine("- response sent");
            }

            stream.Close();
            Console.WriteLine("done!");
            Console.Read();
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c# SSL TCPServer 卡在 SsLStream.AuthenticateAsServer() 的相关文章

随机推荐

  • 如何使用 ggplot 生成非标准绘图类型?

    我想用 ggplot 制作一个看起来与此非常接近的图 在这里找到 http learnr files wordpress com 2009 07 chapter04 04 05 r png 然而 我想绘制条件范围 而不是频率 这是我想要在
  • R 中的形式参数“数据”与多个实际参数匹配

    当我在 R 中运行以下代码时 library mclust data iris mc lt Mclust iris 1 4 3 plot mc data iris 1 4 what classification dimens c 3 4 t
  • 遗留应用程序的迁移:EJB3或Spring

    我有旧应用程序使用struts ejb2 0 hibernate v3 0在 JBoss v4 0 上运行 现在我们已经将该应用程序迁移到新技术堆栈 我们正在探索pros and cons不同的技术堆栈 现在我们有两种选择 EJB3 0 J
  • 如何向随机频道发送消息?

    我正在尝试制作一个机器人 当用户发送特定消息时 它会向随机选择的频道发送随机消息 除了获取所有频道 ID 并手动将它们添加到列表中 然后从该列表中随机选择之外 我不知道如何解决这个问题 但是这种方法存在一些非常大的问题 而且它不起作用 我尝
  • 0除以无穷大一定是0吗?

    根据这个问题 https stackoverflow com questions 1613988 dividing by infinity n inf预计为零n 0 什么时候呢n 0 根据 IEEE 754 0 inf 0总是正确的 从数学
  • 如何在微风中全局应用 MaxExpansionDepth 或应用到整个控制器

    我找到了这个答案 MaxExpansionDepth 与最新的 webapi 和微风 https stackoverflow com questions 19668693 maxexpansiondepth with latest weba
  • 在 Rstudio 中使用 knitr 和在命令行中使用 knit2html 时,HTML 输出有所不同

    我正在尝试使用 knit 从 R markdown 文件生成 html 文档 当我在 R studio 中使用 knit html 按钮时 它工作正常 并且得到了我想要的输出 然而 当我在命令行中使用 knit2html 时 输出 html
  • 在 mono/Linux 下从命名管道读取/写入

    我想从 Linux 下的命名管道 FIFo 队列中读取 写入 我已经尝试了标准类 StreamWriter 和 System IO 中的其他类 但它失败了 因为它正在使用查找 有人曾经使用 Mono 从命名管道中写入 读取过吗 我正在设法阅
  • ES6 导入的执行顺序(HTML 和代码)

    如果我有以下情况 我说得对吗 你不能 100 确定three js将被处决AFTER one js and two js 但是 如果我有 我说得对吗 我可以有信心three js将被处决AFTER one js and two js 这个很
  • 不确定如何使用 CICrop 裁剪图像

    我正在尝试使用 CICrop 裁剪图像 但是当我尝试裁剪时 它崩溃并显示以下错误消息 由于未捕获的异常 NSUnknownKeyException 而终止应用程序 原因 setValue forUndefinedKey 这个类 不符合键的键
  • Entity Framework 4 CTP 4 Code First:如何使用非常规的主键和外键名称

    实体框架 4 中是否有方法 如果重要的话使用 CTP4 和 Code First 来更改用于自动识别主键和外键的约定 我尝试将 EF 与旧数据库一起使用 该旧数据库使用 pk fk 前缀而不是 id 后缀来标记键 此外 地址表具有多个外键
  • 无法在docker上安装jenkins的建议插件

    我已经通过docker启动了jenkins 它已经以管理员模式启动 输入密码后 当我选择安装建议的插件时 大部分安装都会失败 发布当我创建 jenkins 用户并导航到 jenkins 主页时 它显示错误 如下面的屏幕截图所示 通过以下命令
  • 某些实体变量的 Spring Security

    是否可以使用 Spring Security 来安全更新某些实体属性 例如 如果我有一个用户实体 我希望 ROLE USER 能够修改 更新用户的所有属性 除了可由 ROLE ADMIN 更新的活动列之外 我还没有找到Spring Secu
  • 相对布局中的百分比宽度

    我正在研究登录的表单布局Activity在我的 Android 应用程序中 下图是我想要的样子 我能够通过以下方式实现此布局XML 问题是 这有点hackish 我必须对主机 EditText 的宽度进行硬编码 具体来说 我必须指定 and
  • 是否有创建 BPMN 的 Java API? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有没有办法以编程方式创建BPMN 2 0 http en wikipedia org wiki Business Process Mode
  • Symfony2 minify 无需 java 或 node

    我无法访问共享主机上的 java 或 node 有没有办法缩小服务器端 这样我就可以继续使用 assetic 而不需要这些引擎 Uglify 使用node yui compressor 无论如何已弃用 使用java Thanks 似乎有 2
  • 已安装的 gem 列表?

    我可以调用 Ruby 方法来获取已安装 gem 的列表吗 我想解析的输出gem list 有其他方法可以做到这一点吗 这列出了我安装的所有 gem gem query local http guides rubygems org comma
  • 如何使用 Moment.js 将日期验证为指定格式?

    我无法找到有关如何使用 moment js 验证日期输入以确保其格式为 2017 12 31T23 59 59Z 的现有问题 答案 鉴于我有一个日期字符串 2017 12 31T23 59 59Z 如何验证日期字符串严格采用指定的格式 YY
  • 如何使用sidenav的EventEmitter(onClose)

    我想检查一下我的
  • c# SSL TCPServer 卡在 SsLStream.AuthenticateAsServer()

    故事情节 我想用 C 创建我自己的网络服务器 第一次尝试 进展顺利 我正在使用Visual Studio 到代码申请和火狐浏览器检查如果我做得对的话 并且我成功地制作了一个基本的 TCPServer 当我尝试向其添加 SSL 支持时 遇到了