SslStream,禁用会话缓存

Vla*_*lad 11 c# ssl-certificate

MSDN文档说:

如果可能,框架会在创建SSL会话时对其进行缓存,并尝试将缓存会话重新用于新请求.尝试重用SSL会话时,Framework使用ClientCertificates的第一个元素(如果有),或者如果ClientCertificates为空,则尝试重用匿名会话.

如何禁用此缓存?

目前我遇到了重新连接到服务器的问题(即,第一个连接工作正常,但尝试重新连接服务器会中断会话).重新启动应用程序有帮助(但当然仅适用于第一次连接尝试).我假设问题根是缓存.

我用嗅探器检查了数据包,区别仅在于客户端Hello消息的单个位置:

第一次连接到服务器(成功):

截图

第二次连接尝试(没有程序重启,失败):

截图

差异似乎只是会话标识符.

PS我想避免使用第三方SSL客户端.有合理的解决方案吗?

这是来自ru.stackoverflow 的这个问题的翻译

ruf*_*nov 7

缓存在SecureChannel内部处理,SecureChannel是包装SSPI的内部类,由SslStream使用。我看不到任何可用于禁用客户端连接的会话缓存的点。

您可以使用反射清除连接之间的缓存:

var sslAssembly = Assembly.GetAssembly(typeof(SslStream));

var sslSessionCacheClass = sslAssembly.GetType("System.Net.Security.SslSessionsCache");

var cachedCredsInfo = sslSessionCacheClass.GetField("s_CachedCreds", BindingFlags.NonPublic | BindingFlags.Static);
var cachedCreds = (Hashtable)cachedCredsInfo.GetValue(null);

cachedCreds.Clear();
Run Code Online (Sandbox Code Playgroud)

但这是非常糟糕的做法。考虑修复服务器端。

  • 或修复Microsoft的SslClient。 (2认同)