4 Stimmen

Timeout: BeginAuthenticateAsClient vs AuthenticateAsClient Timeout: BeginAuthenticateAsClient vs AuthenticateAsClient

Ich entwickle einen .NET-Dienst, der zu versuchen, eine sichere Verbindung zu einem Server herzustellen. Der Dienst weiß im Voraus nicht, ob der Server sichere Verbindungen unterstützt. Deshalb versuche ich einfach, eine sichere Verbindung herzustellen und falls das scheitert, falle ich auf die unsichere Verbindung zurück.

Ich verwende TcpClient zusammen mit SslStream:

tcpClient.BeginConnect(hostname, port, Start, null);

private void Start(IAsyncResult asyncResult)
{
  X509CertificateCollection certCollection = new X509CertificateCollection();
  certCollection.Add(new X509Certificate2("cert.p12", "pw"));

  SslStream sslStream = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateCertificate));

  sslStream.ReadTimeout = 2000;

  sslStream.BeginAuthenticateAsClient("name", certCollection, SslProtocols.Tls, false, AuthenticateCallback, sslStream);
}

private void AuthenticateCallback(IAsyncResult asyncResult)
{
stream.ReadTimeout = -1;

// Sichere Verbindung wurde hergestellt
}

Falls der Server die angeforderte Verschlüsselung nicht unterstützt, dauert es 2 Minuten, bevor die Rückruffunktion aufgerufen wird. Wenn stattdessen die synchrone Methode AuthenticateAsClient() verwendet wird, dauert es nur die erwarteten 2 Sekunden (wie durch das Setzen des ReadTimeout angefordert):

sslStream.AuthenticateAsClient("ESLD Server", certCollection, SslProtocols.Tls, false);

Warum gilt das Timeout nur für die synchrone Methode? Wie kann ich die Rückrufzeit für die asynchrone Methode reduzieren? Oder gibt es einen besseren Ansatz, um zu überprüfen, ob der Server sichere Verbindungen unterstützt?

0voto

Luc VdV Punkte 968

Ich kann keine definitive Antwort geben, sondern nur auf einige Probleme eingehen, die ich in Bezug darauf erlebt habe.

Auf welchem Betriebssystem haben Sie das versucht?

Was ich festgestellt habe, ist, dass die gegenseitige Authentifizierung, wenn die Clientverbindung durch asynchrone Aufrufe (BeginXxxx mit Rückrufen) eingerichtet wird, auf Windows XP einwandfrei funktioniert, aber auf Windows 7 oder neuer nicht funktioniert. Die synchronen Methoden funktionieren von XP bis 8.1 einwandfrei, aber asynchron liefert bei allen außer XP die seltsamsten Ergebnisse.

In Windows 7 ist es so, als würden die Zertifikate, die Sie bei BeginAuthenticateAsClient übergeben, nie auf der anderen Seite ankommen. Der vom SslStream-Konstruktor eingerichtete Remotezertifikatvalidierungsrückruf erhält Null für die Zertifikats- und Kettenparameter und RemoteCertificateNotAvailable für den SslPolicyErrors-Parameter. Verwenden Sie AuthenticateAsClient anstelle von [BeginAuthenticateAsClient + Rückruf], und das Problem verschwindet.

In Windows 8.1 war es noch seltsamer: Als ich den genau gleichen Code dort ausführte, wurde der Rückruf von BeginAuthenticateAsClient aufgerufen, der das Ende des Authentifizierungsprozesses signalisierte, bevor der entfernte Zertifikatsauthentifizierungsrückruf, der vom SslStream-Konstruktor eingerichtet wurde, auf der entfernten Seite aufgerufen wurde, sodass die Serveranwendung noch keine Gelegenheit hatte, das Clientzertifikat entweder zu akzeptieren oder abzulehnen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X