C# 如何清除任何SSL证书数据

C# 如何清除任何SSL证书数据,c#,ssl,certificate,C#,Ssl,Certificate,我有一个客户端-服务器设置。 客户端创建一个代理以便与服务器通信。当通信协议为HTTPS时,代理通过以下线路侦听SSL证书验证事件: ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate); ValidateRemoteCertificate方法处理证书异常 在客户端中,用户可以选择3个安全级别中的一

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

ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);
ValidateRemoteCertificate方法处理证书异常

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

到目前为止还不错

情况如下:

  • 客户端加载用户已接受的预定义安全级别的介质,并与服务器建立连接,而不传播任何证书问题
  • 用户断开客户端与服务器的连接(通过一个特殊按钮)
  • 用户尝试重新连接客户端。在此阶段,客户机能够通过测试按钮测试连接。尽管已为连接测试创建了新代理,并且已从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 { }
            }
        }