简体   繁体   English

c#SSL TCPServer卡在SsLStream.AuthenticateAsServer()

[英]c# SSL TCPServer stuck at SsLStream.AuthenticateAsServer()

Storyline: 故事情节:

I wanted to make my very own webserver in c#(first attempt). 我想在c#中创建我自己的网络服务器(第一次尝试)。 It went well(I was using Visual Studio to code the application and Firefox to check if I was doing right) and I managed to make a basic TCPServer. 它进展顺利(我使用Visual Studio编写应用程序代码并使用Firefox来检查我是否正确)并且我设法制作了一个基本的TCPServer。 As I was trying to add SSL support to it I encountered a problem. 当我试图添加SSL支持时,我遇到了一个问题。

  • I have been trying to authenticate as a TcpServer with SSL support using SSLStream.AuthenticateAsServer([self-signed certificate]) for the last 7 days 在过去的7天里,我一直尝试使用SSLStream.AuthenticateAsServer([自签名证书])作为支持SSL的TcpServer进行身份验证

Problem: 问题:

As I get the [Upgrade-Insecure-Requests: 1] from my beloved Firefox I'm trying to [SSLStream.AuthenticateAsServer([self-signed certificate])]. 当我从我心爱的Firefox获得[Upgrade-Insecure-Requests:1]时,我正在尝试[SSLStream.AuthenticateAsServer([自签名证书])]。 Doing that my code is stuck(but doesn't freeze/crash) at this line while my Firefox is just loading forever without seeming to send me a Response. 这样做我的代码卡在这条线上(但没有冻结/崩溃) ,而我的Firefox只是永远加载,而不是似乎发送给我一个响应。

Code: 码:


starting my server 启动我的服务器


 TCPServer.ServerStart(8080); 


(listener is being defined in my TCPServer class) (在我的TCPServer类中定义了监听器)

 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 ) (由于对SSL没有任何了解, 我使用了这个示例代码

Upgrade-Insecure-Requests doesn't mean that the server can encrypt the current connection. Upgrade-Insecure-Requests并不意味着服务器可以加密当前连接。 Firefox still expects an unencrypted HTTP/1.x response. Firefox仍然期望未加密的HTTP / 1.x响应。 But this response can redirect it to another URL — perhaps on another port — where SSL will be enabled right from the start. 但是这个响应可以重定向到另一个URL - 可能在另一个端口 - 从一开始就启用SSL。

See example 8 in the Upgrade Insecure Requests specification . 请参阅升级不安全请求规范中的示例8

I made it! 我做到了! The problem was that (in my thread) I was using a X509Certificate public-made cert with no keys in it instead of a X509Certificate2 private-cert with keys in it. 问题是(在我的线程中)我使用的是X509Certificate公共证书,其中没有密钥,而不是带有密钥的X509Certificate2 private-cert。 That's why I got hangs in my code at SslStream.AuthenticateAsServer();. 这就是我在SslStream.AuthenticateAsServer();的代码中挂起的原因。 @Vasiliy Faronov answer did also help me very much(I needed to add a 307 header to port 443), thx. @Vasiliy Faronov的回答也对我很有帮助 (我需要在端口443上添加一个307标题),thx。

Anyways here's an example of how to send an index.html to your webbrowser through https in tcp-level: 无论如何,这里是一个如何通过tcp级别的https将index.html发送到您的webbrowser的示例:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 C# 中,在服务器端使用 SslStream.AuthenticateAsServer() 有什么意义? - In C# what is the point of using SslStream.AuthenticateAsServer() on the server side? SslStream.AuthenticateAsServer 挂起 - SslStream.AuthenticateAsServer hangs SslStream.AuthenticateAsServer证书链 - SslStream.AuthenticateAsServer certificate chain sslStream.AuthenticateAsServer忽略RemoteCertificateValidationCallback - sslStream.AuthenticateAsServer ignores RemoteCertificateValidationCallback 如何为SslStream.AuthenticateAsServer()创建证书? - How to create certificate for SslStream.AuthenticateAsServer()? SslStream.AuthenticateAsServer异常-服务器模式SSL必须使用带有关联私钥的证书 - SslStream.AuthenticateAsServer exception - The server mode SSL must use a certificate with the associated private key SslStream.AuthenticateAsServer 抛出服务器模式 SSL 必须使用具有关联私钥的证书 - SslStream.AuthenticateAsServer throws The server mode SSL must use a certificate with the associated private key 为什么sslStream.AuthenticateAsServer不需要UAC和替代方法 - Why does sslStream.AuthenticateAsServer require no UAC and alternatives 为什么SslStream.AuthenticateAsServer从Ubuntu失败但从Windows 10失败 - Why would SslStream.AuthenticateAsServer fail from Ubuntu but not from Windows 10 从SQL加载时,SslStream.AuthenticateAsServer证书失败,但从嵌入式文件加载时,SslStream.AuthenticateAsServer证书有效 - SslStream.AuthenticateAsServer certificate fails when loaded from SQL, but works when loaded from an embedded file
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM