4

我正在开发一个 .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);

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

4

1 回答 1

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 构造函数设置的远程证书身份验证回调。 ,因此服务器应用程序还没有机会接受或拒绝客户端证书。

于 2015-03-23T15:20:04.077 回答