【发布时间】:2013-11-05 16:12:44
【问题描述】:
我有一个在 .NET 4.5 上用 C# 编写的客户端和服务器应用程序,它们使用 SslStream 进行通信。
但是,在客户端或服务器首次启动时,设置 SslStream 非常慢,通常需要 8-10 秒左右。
我已经在 dotTrace 中加载了应用程序,发现大部分时间都花在了我们的 AcceptConnection 方法中(它本身是作为 Socket.BeginAccept() 回调的一部分调用的),如图所示下面的 dotTrace 调用跟踪:
生成上述跟踪的 SocketManager 类的源代码是(为简洁起见删除了日志语句):
public void AcceptConnection( ClientCommunicationManager ccm )
{
_ns = new NetworkStream( Sock, true );
_sslStream = new SslStream( _ns, true );
X509Store certs = new X509Store( StoreName.My, StoreLocation.LocalMachine );
certs.Open( OpenFlags.ReadOnly );
X509Certificate2 machineCert = certs.Certificates.Find( X509FindType.FindBySubjectName, Environment.MachineName, true )[ 0 ];
certs.Close( );
_sslStream.AuthenticateAsServer( machineCert, true, SslProtocols.Tls12, true );
_sslStream.BeginRead( ReceiveBuffer, 0, ReceiveBuffer.Length, ReceiveData, ccm );
}
我们的 ClientCommunicationManager 类中的以下代码是导致调用 AcceptConnection 函数的原因:
private void AcceptClientConnection( IAsyncResult ar )
{
ClientCommunicationManager ccm = ar.AsyncState as ClientCommunicationManager;
Socket acceptedSocket = _listenerSocket.EndAccept( ar );
SocketManager manager = new SocketManager( ccm, acceptedSocket );
_listenerSocket.BeginAccept( AcceptClientConnection, this );
manager.AcceptConnection( this );
}
dotTrace 声称该函数中 97.95% 的时间都花在了对“ProcessAuthentication”的调用上,这不是我明确调用的,所以我不知道是什么引发了该调用。
服务器具有有效的 CA 签名证书,并安装在本地计算机个人存储中。
在过去的几天里,我一直在搜索谷歌,结果遇到了一堵砖墙。 有关如何确定此延迟原因的任何建议?
【问题讨论】:
-
clientCertificateRequired(2nd) 参数到AuthenticateAsServer是false时是否更快?当这是true时,服务器发送可接受的客户端证书颁发者列表(显然取自可能相当大的机器。在我的机器上,它发送大约 200 个单独的条目(导致大约 20KB 的数据被发送到客户端),如果您的更多,可能会导致您看到的性能不佳。 -
感谢您的建议。不过,我进行了更改,但仍然需要很长时间(13 秒)。
-
对问题的编辑(包括新的 dotTrace 输出)。似乎我错误地追踪了这个问题。 AuthenticateAsServer 方法本身不一定是问题 - 这是我没有明确调用的 ProcessAuthentication 方法。
-
它可能正在向 CRL 发出 Web 请求,以验证客户端证书没有被颁发者吊销。您可以尝试禁用吊销检查(认为这是
AuthenticateAsServer的最后一个参数)。 -
我自己也很早就做出了改变,我认为 CRL 检查可能会很慢。不幸的是,它似乎没有帮助。我可能用我原来的问题误导了你。为了澄清,我现在对这个问题进行了一些相当重要的编辑。从上面新的 dotTrace 输出的外观来看,我不太确定 AuthenticateAsServer 方法与它有什么关系。
标签: c# .net performance ssl