2016-07-10 18 views
1

Ich arbeite an einer größeren C# Sockets-App, die sowohl die Server- als auch die Client-Authentifizierung über SSL verwendet. Um die anderen Teile der App auf meinem lokalen Computer zu testen, muss ich die Zertifizierungsprüfung deaktivieren. Ich habe versucht, ServerCertificateValidatioNCallback zu überschreiben, wie in einigen anderen Orten vorgeschlagen, aber ich bekomme weiterhin eine Ausnahme. Ich teste mit selbstsignierten Zertifikaten, die mit OpenSSL erstellt wurden.Disable Zertifikatsüberprüfung für AuthenticateAsServer scheint nicht zu funktionieren

Die Artikel mit Lösungen, die ich habe versucht:

Die Ausnahme Ich erhalte:

StackTrace: at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception) 
    at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) 
    at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) 
    at System.Net.Security.SslStream.AuthenticateAsServer(X509Certificate serverCertificate, Boolean clientCertificateRequired, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation) 

Ich habe meinen Server-Code bis auf die folgenden reduziert:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 
X509Certificate2 cert = new X509Certificate2("server.pfx", "password"); 

IPAddress ip = IPAddress.Parse("127.0.0.1"); 
TcpListener server = new TcpListener(ip, 8000); 
server.Start(); 

TcpClient client = server.AcceptTcpClient(); 
Console.WriteLine(client.Client.RemoteEndPoint.ToString() + ":" + ((IPEndPoint)client.Client.RemoteEndPoint).Port + " connected"); 
SslStream ssl = new SslStream(client.GetStream(), false); 
ssl.AuthenticateAsServer(cert, true, SslProtocols.Tls, false); 

Und der Client-Code ist wie folgt:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 
TcpClient client = new TcpClient("127.0.0.1", 8000); 
X509Certificate2Collection coll = new X509Certificate2Collection(); 
coll.Add(new X509Certificate2("client.pfx", "password")); 
byte[] data = Encoding.UTF8.GetBytes("Hello from the client!"); 

using (SslStream ssl = new SslStream(client.GetStream(), false)) 
{ 
    ssl.AuthenticateAsClient("127.0.0.1", coll, SslProtocols.Tls, false); 
    ssl.Write(data, 0, data.Length); 
    data = new Byte[8192]; 
    int bytes = 0; 
    string resp = ""; 

    do 
    { 
    bytes = ssl.Read(data, 0, data.Length); 
    if (bytes > 0) resp += System.Text.Encoding.ASCII.GetString(data, 0, bytes); 
    } 
    while (bytes > 0); 

    Console.WriteLine("Response: " + resp); 
} 

client.Close(); 

Die Ausnahme tritt auf AuthenticateAsServer und AuthenticateAsClient. Das Design der Anwendung erfordert die Verwendung von Clientzertifikaten.

Ich habe versucht, die PFX-Dateien in den Zertifikatsspeicher zu importieren, machte keinen Unterschied im Ergebnis.

Ich habe auch versucht, die selbst-signierten Zertifikate und private Schlüssel mit makecert und die Konvertierung in PFX mit pvk2pfx.exe, machte keinen Unterschied in das Ergebnis. Mein Gedanke war, dass es vielleicht ein Problem war, dass sie auf einer anderen Maschine erstellt wurden.

Antwort

1

Offenbar ist diese Linie nicht genug:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

ich meine SslStream von ändern musste: (Server)

SslStream ssl = new SslStream(client.GetStream(), false); 

und (Client)

using (SslStream ssl = new SslStream(client.GetStream(), false)) 

An: (Server)

SslStream ssl = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateCert)); 

und (Client)

using (SslStream ssl = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateCert))) 

und fügen Sie die folgende Methode:

public static bool ValidateCert(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) 
{ 
    return true; // Allow untrusted certificates. 
} 

Anscheinend hat Vorrang vor dem: ServicePointManager.ServerCertificateValidationCallback delegieren.

Offenbar muss ich jetzt herausfinden, wie ValidateCert geändert werden kann, um nicht vertrauenswürdige Zertifikate zuzulassen.