我正在开发一种尝试与服务器建立安全连接的.NET服务。如果服务器支持安全连接,则服务事先不知道。这就是为什么我只是尝试建立一个安全的连接,如果失败了,我将回退到不安全的连接。
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);
为什么超时仅适用于同步方法? 如何减少异步方法的回调时间? 或者是否有更好的方法来检查服务器是否支持安全连接?
答案 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构造函数在远程端调用,因此服务器应用程序还没有机会接受或拒绝客户端证书。