ValidateRemoteCertificate

ValidateRemoteCertificate

本文介绍了如何清除任何SSL证书数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a client - server setup.The client creates a proxy in order to communicate with the server. When the communication protocol is HTTPS the proxy listens for SSL certificate validation event via the following line:

ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);

ValidateRemoteCertificate方法处理证书异常。

The ValidateRemoteCertificate method deals with Certificate exceptions.

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

In the client the user can select one of 3 security levels: low, medium and high.In low level the ValidateRemoteCertificate method ignores any errors and always return true.In Medium level the ValidateRemoteCertificate method fires an event that notifies the client of the problem. At this stage a message appears to the user informing him that the certificate is problematic and allows the user to select whether to continue and accept the connection with the server or decline.In High level the ValidateRemoteCertificate method declines the connection for any error.

到目前为止,一切都很好。

So far so good.

该场景如下:


  1. 客户端加载具有用户和连接已经接受的预定义安全级别中是与服务器建立的,没有传播任何证书问题。

  2. 用户通过一个特殊按钮将客户端与服务器断开连接。

  3. 用户尝试重新连接客户端。在此阶段,客户端可以通过测试按钮测试连接。尽管已为连接测试创建了新代理,并且已从ServerCertificateValidationCallback(特定代理类型的)中清除了所有ValidateRemoteCertificate方法,但是该测试方法仍返回成功。同样,没有问题的证书不会触发任何事件,并且不会调用ValidateRemoteCertificate方法。

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

The behavior which I'm trying to achieve is that when the test is performed, the ServerCertificateValidationCallback will behave as if it's the first call to it after the client has been launched and the ValidateRemoteCertificate would come into play.

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

I tried looking for any method that clears any delegates / events in the ServicePointManager but I couldn't find any.

这里是否有可以清除的缓存?
我希望情况已经足够清楚。

Is there a cache here that can be cleared?I hope the scenario is clear enough.

推荐答案

我知道已经快4年了,但是我刚刚有了

I know it's been almost 4 years, but I just had this same issue and wanted to share my solution incase anyone else finds this.

我找不到任何内置的方式来处理此问题,因此查看了ServicePoint的源代码和ServicePointManager,这是我想出的:

I couldn't find any built in way to handle this, so looked at the source code of ServicePoint and ServicePointManager and here's what I came up with:

    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 { }
        }
    }

这篇关于如何清除任何SSL证书数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-22 02:36