如何清除任何SSL证书数据

我有一个客户端 – 服务器设置。 客户端创建代理以与服务器通信。 当通信协议为HTTPS时,代理通过以下行侦听SSL证书validation事件:

ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate); 

ValidateRemoteCertificate方法处理证书exception。

在客户端中,用户可以选择3个安全级别中的一个:低,中和高。 在低级别,ValidateRemoteCertificate方法忽略任何错误并始终返回true。 在中级,ValidateRemoteCertificate方法触发一个事件,通知客户端该问题。 在此阶段,向用户显示消息,通知他证书存在问题,并允许用户选择是继续并接受与服务器的连接还是拒绝。 在High级别,ValidateRemoteCertificate方法拒绝任何错误的连接。

到现在为止还挺好。

方案如下:

  1. 客户端加载了预定义的安全级别“中”,该级别已被用户接受,并且与服务器建立连接,而不会传播任何证书问题。
  2. 用户断开客户端与服务器的连接(通过特殊按钮)。
  3. 用户尝试重新连接客户端。 在此阶段,客户端可以通过测试按钮测试连接。 尽管已为连接测试创建了新代理,并且已从ServerCertificateValidationCallback(特定代理类型)中清除了所有ValidateRemoteCertificate方法,但测试方法返回成功。 此外,没有为有问题的证书触发事件,并且不调用ValidateRemoteCertificate方法。

我试图实现的行为是,当执行测试时,ServerCertificateValidationCallback将表现为在客户端启动并且ValidateRemoteCertificate发挥作用后它是对它的第一次调用。

我试图寻找任何方法来清除ServicePointManager中的任何委托/事件,但我找不到任何。

这里有缓存可以清除吗? 我希望这个场景足够清晰。

我知道这已经差不多4年了,但我只是遇到了同样的问题,想要分享我的解决方案,任何人都会发现这一点。

我找不到任何内置的方法来处理这个,所以看看ServicePoint和ServicePointManager的源代码,这就是我想出的:

  public void EnsureNoServicePointCertificate(Uri uri) { // find the service point for the Uri ServicePoint sp = ServicePointManager.FindServicePoint(uri); // Check if there is a service point and there is a certificate if (sp != null && sp.Certificate != null) { try { // ServicePointManager has a hashtable (private static Hashtable s_ServicePointTable) of all service points Type servicePointType = sp.GetType(); // ServicePoint.LookupString is the key for the hashtable PropertyInfo lookupStringProperty = servicePointType.GetProperty("LookupString", BindingFlags.Instance | BindingFlags.NonPublic); string lookupString = (string)lookupStringProperty.GetValue(sp, null); // Get the hashtable from ServicePointManager Hashtable s_ServicePointTable = (Hashtable)typeof(ServicePointManager).InvokeMember("s_ServicePointTable", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField, null, null, null); // ServicePointManager locks the hashtable and calls // s_ServicePointTable.Remove(servicePoint.LookupString); lock (s_ServicePointTable) { s_ServicePointTable.Remove(lookupString); } // At this point, ServicePointManager calls // servicePoint.ReleaseAllConnectionGroups(); MethodInfo release = servicePointType.GetMethod("ReleaseAllConnectionGroups", BindingFlags.Instance | BindingFlags.NonPublic); release.Invoke(sp, null); } catch { } } }