2016-06-21 13 views
2

Ich versuche, meinen eigenen HTTPS-Proxy-Server zu erstellen. Aus irgendeinem Grund habe ich eine Ausnahme, wenn ich versuche, von sslstream Objekt zu lesen. Hier ist es:C# SSLStream-Lesefunktion löst IOException

Eine nicht behandelte Ausnahme des Typs ‚System.IO.IOException‘ aufgetreten in System.dll

Zusätzliche Informationen: Daten können nicht von der Transportverbindung lesen: Ein Verbindungsversuch, weil die gescheiterten Der verbundene Teilnehmer hat nach einer gewissen Zeit nicht richtig geantwortet oder die Verbindung ist fehlgeschlagen, weil der verbundene Host nicht geantwortet hat.

Hier ist mein Code:

public Server() 
    { 
     m_portnumber = 4434; 
     m_tcplistener = new TcpListener(IPAddress.Any, m_portnumber); 
     m_cert = createCertificate(); 
    } 
    public void start() 
    { 
     m_tcplistener.Start(); 
     while (true) 
     { 
      TcpClient client = m_tcplistener.AcceptTcpClient(); 
      ClientHandler(client); 
     } 
    } 

    private void ClientHandler(TcpClient client) 
    { 
     // A client has connected. Create the 
     // SslStream using the client's network stream. 
     SslStream sslStream = new SslStream(
      client.GetStream(), false); 
     // Authenticate the server but don't require the client to authenticate. 
     try 
     { 
      sslStream.AuthenticateAsServer(m_cert, 
       false, SslProtocols.Tls, true); 
      // Display the properties and settings for the authenticated stream. 
      DisplaySecurityLevel(sslStream); 
      DisplaySecurityServices(sslStream); 
      DisplayCertificateInformation(sslStream); 
      DisplayStreamProperties(sslStream); 

      // Set timeouts for the read and write to 5 seconds. 
      sslStream.ReadTimeout = 5000; 
      sslStream.WriteTimeout = 5000; 
      // Read a message from the client. 
      Console.WriteLine("Waiting for client message..."); 
      string messageData = ReadMessage(sslStream); 
      Console.WriteLine("Received: {0}", messageData); 
     } 
     catch (AuthenticationException e) 
     { 
      Console.WriteLine("Exception: {0}", e.Message); 
      if (e.InnerException != null) 
      { 
       Console.WriteLine("Inner exception: {0}", e.InnerException.Message); 
      } 
      Console.WriteLine("Authentication failed - closing the connection."); 
      sslStream.Close(); 
      client.Close(); 
      return; 
     } 
     finally 
     { 
      // The client stream will be closed with the sslStream 
      // because we specified this behavior when creating 
      // the sslStream. 
      sslStream.Close(); 
      client.Close(); 
     } 
    } 
    static string ReadMessage(SslStream sslStream) 
    { 
     // Read the message sent by the server. 
     // The end of the message is signaled using the 
     // "<EOF>" marker. 
     byte[] buffer = new byte[2048]; 
     StringBuilder messageData = new StringBuilder(); 
     int bytes = -1; 
     do 
     { 
      bytes = sslStream.Read(buffer, 0, buffer.Length); 

      // Use Decoder class to convert from bytes to UTF8 
      // in case a character spans two buffers. 
      Decoder decoder = Encoding.UTF8.GetDecoder(); 
      char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)]; 
      decoder.GetChars(buffer, 0, bytes, chars, 0); 
      messageData.Append(chars); 
      // Check for EOF. 
      if (messageData.ToString().IndexOf("<EOF>") != -1) 
      { 
       break; 
      } 
     } while (bytes != 0); 

     return messageData.ToString(); 
    } 
    static void DisplaySecurityLevel(SslStream stream) 
    { 
     Console.WriteLine("Cipher: {0} strength {1}", stream.CipherAlgorithm, stream.CipherStrength); 
     Console.WriteLine("Hash: {0} strength {1}", stream.HashAlgorithm, stream.HashStrength); 
     Console.WriteLine("Key exchange: {0} strength {1}", stream.KeyExchangeAlgorithm, stream.KeyExchangeStrength); 
     Console.WriteLine("Protocol: {0}", stream.SslProtocol); 
    } 
    static void DisplaySecurityServices(SslStream stream) 
    { 
     Console.WriteLine("Is authenticated: {0} as server? {1}", stream.IsAuthenticated, stream.IsServer); 
     Console.WriteLine("IsSigned: {0}", stream.IsSigned); 
     Console.WriteLine("Is Encrypted: {0}", stream.IsEncrypted); 
    } 
    static void DisplayStreamProperties(SslStream stream) 
    { 
     Console.WriteLine("Can read: {0}, write {1}", stream.CanRead, stream.CanWrite); 
     Console.WriteLine("Can timeout: {0}", stream.CanTimeout); 
    } 
    static void DisplayCertificateInformation(SslStream stream) 
    { 
     Console.WriteLine("Certificate revocation list checked: {0}", stream.CheckCertRevocationStatus); 

     X509Certificate localCertificate = stream.LocalCertificate; 
     if (stream.LocalCertificate != null) 
     { 
      Console.WriteLine("Local cert was issued to {0} and is valid from {1} until {2}.", 
       localCertificate.Subject, 
       localCertificate.GetEffectiveDateString(), 
       localCertificate.GetExpirationDateString()); 
     } 
     else 
     { 
      Console.WriteLine("Local certificate is null."); 
     } 
     // Display the properties of the client's certificate. 
     X509Certificate remoteCertificate = stream.RemoteCertificate; 
     if (stream.RemoteCertificate != null) 
     { 
      Console.WriteLine("Remote cert was issued to {0} and is valid from {1} until {2}.", 
       remoteCertificate.Subject, 
       remoteCertificate.GetEffectiveDateString(), 
       remoteCertificate.GetExpirationDateString()); 
     } 
     else 
     { 
      Console.WriteLine("Remote certificate is null."); 
     } 
    } 
    private static void DisplayUsage() 
    { 
     Console.WriteLine("To start the server specify:"); 
     Console.WriteLine("serverSync certificateFile.cer"); 
     Environment.Exit(1); 
    } 

    private X509Certificate createCertificate() 
    { 
     byte[] c = Certificate.CreateSelfSignCertificatePfx(
        "CN=localhost", //host name 
        DateTime.Parse("2015-01-01"), //not valid before 
        DateTime.Parse("2020-01-01"), //not valid after 
        "sslpass"); //password to encrypt key file 
     using (BinaryWriter binWriter = new BinaryWriter(File.Open(@"cert.pfx", FileMode.Create))) 
     { 
      binWriter.Write(c); 
     } 
     return new X509Certificate2(@"cert.pfx", "sslpass"); 
    } 
} 
+0

Das Problem tritt in dieser Zeile auf: bytes = sslStream.Read (buffer, 0, buffer.Length); –

+0

Natürlich tut es das. Sie legen ein Lesezeitlimit fest und MSDN sagt "Wenn die Leseoperation nicht innerhalb der Zeit abgeschlossen wird, die von dieser Eigenschaft angegeben wird, löst die Leseoperation eine IOException aus." Was hast du erwartet? –

+0

(Wenn Sie erwartet haben, EOF mit 'messageData.ToString(). IndexOf (" ") zu erkennen, wird das nur dann erreicht, wenn der Client Ihnen die Bytes' 'sendet. Tut Ihr Client das? Ich vermute, dass Ihr Client ein Webbrowser ist, bezweifle ich. –

Antwort

2

Dies ist kein SSL-Fehler, sondern ein TCP ein. Sie stellen eine Verbindung zu einem IP/Port-Paar her, das nicht abhört. Ist eine aktive Ablehnung, so ist es nicht so, als ob Sie die IP erreichen und Ihnen sagen, dass es keinen Port gibt. Ist ein Timeout, könnte dies eine ungültige IP bedeuten oder die Firewall des Ziels ignoriert Sie (absichtlich).

Mein erster Verdacht wäre Linie m_portnumber = 4434;. Dies ist eine ungewöhnliche Portnummer. Sie sind sicher, dass es sich nicht um einen Tippfehler handelt, und Sie wollten den HTTPS-üblichen Port (443)? Wenn Sie wirklich 4434 meinen, müssen Sie die Netzwerkverbindung überprüfen. Stellen Sie sicher, dass die IP ordnungsgemäß aufgelöst wird, erreichbar ist, das Ziel überwacht und die Firewall Sie einloggt.

+0

Auch wenn ich die Portnummer 443 verwende, bekomme ich die selbe Ausnahme –

Verwandte Themen