超时:BeginAuthenticateAsClient与AuthenticateAsClient

时间:2014-02-28 14:29:53

标签: c# .net ssl tcpclient sslstream

我正在开发一种尝试与服务器建立安全连接的.NET服务。如果服务器支持安全连接,则服务事先不知道。这就是为什么我只是尝试建立一个安全的连接,如果失败了,我将回退到不安全的连接。

我与TcpClient一起使用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;

// secure connection has been established
}

如果服务器不支持请求的加密,则在调用回调方法之前需要2分钟。使用同步方法AuthenticateAsClient()只需要预期的2秒(根据设置ReadTimeout的要求):

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

为什么超时仅适用于同步方法? 如何减少异步方法的回调时间? 或者是否有更好的方法来检查服务器是否支持安全连接?

1 个答案:

答案 0 :(得分:0)

我无法给出明确的答案,只是扩展我遇到的一些问题。

你在尝试使用什么操作系统?

我发现相互身份验证,如果通过异步调用(带回调的BeginXxxx)建立客户端连接,则在Windows XP上运行完美,但我无法在Windows 7上运行它或后来。同步方法在XP到8.1中运行良好,但异步对除XP以外的所有方法都给出了最奇怪的结果。

在Windows 7中,就好像您在BeginAuthenticateAsClient中传递的证书从未进入另一方。 SslStream构造函数设置的远程证书验证回调获取证书和链参数的Null,以及SslPolicyErrors参数的RemoteCertificateNotAvailable。 使用AuthenticateAsClient而不是[BeginAuthenticateAsClient + callback],问题就消失了。

在Windows 8.1中,它甚至更奇怪:当我在那里运行完全相同的代码时,调用BeginAuthenticateAsClient的回调,表示身份验证过程完成,远程证书身份验证回调设置之前由SslStream构造函数在远程端调用,因此服务器应用程序还没有机会接受或拒绝客户端证书。