如何忽略证书检查时,SSL(How to ignore the certificate check

2019-06-18 05:30发布

我试图找到一种方法要求HTTPS的资源时,忽略证书检查,到目前为止,我发现在互联网一些有用的物品。

但我仍然有一些问题。 请检阅我的代码。 我只是不明白这是什么代码ServicePointManager.ServerCertificateValidationCallback意思。

当将这种委托方法被调用? 还有一个问题,在哪个地方应该我写这篇文章的代码? 之前ServicePointManager.ServerCertificateValidationCallback执行或前Stream stream = request.GetRequestStream()

public HttpWebRequest GetRequest()
{
    CookieContainer cookieContainer = new CookieContainer();

    // Create a request to the server
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_remoteUrl);

    #region Set request parameters

    request.Method = _context.Request.HttpMethod;
    request.UserAgent = _context.Request.UserAgent;
    request.KeepAlive = true;
    request.CookieContainer = cookieContainer;
    request.PreAuthenticate = true;
    request.AllowAutoRedirect = false;

    #endregion

    // For POST, write the post data extracted from the incoming request
    if (request.Method == "POST")
    {
        Stream clientStream = _context.Request.InputStream;
        request.ContentType = _context.Request.ContentType;
        request.ContentLength = clientStream.Length;

        ServicePointManager.ServerCertificateValidationCallback = delegate(
            Object obj, X509Certificate certificate, X509Chain chain, 
            SslPolicyErrors errors)
            {
                return (true);
            };

            Stream stream = request.GetRequestStream();

            ....
        }

        ....

        return request;
    }
}   

Answer 1:

由于只有一个全局ServicePointManager ,设置ServicePointManager.ServerCertificateValidationCallback将产生的所有后续请求将继承这一政策的结果。 既然是一个全球性的“设置”,它会中将优先设置它在的Application_Start的方法Global.asax中 。

设置回调覆盖缺省行为,你可以自己创建一个自定义的验证程序。



Answer 2:

有兴趣的人基于每个请求基础应用此解决方案,这是一个选项,使用Lambda表达式。 相同的Lambda表达式可以应用到由blak3r所提及的全局过滤器。 这种方法似乎需要.NET 4.5。

String url = "https://www.stackoverflow.com";
HttpWebRequest request = HttpWebRequest.CreateHttp(url);
request.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;

在.NET 4.0,λ表达式可以应用到全局滤波器作为这样

ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;


Answer 3:

这为我工作:

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                        System.Security.Cryptography.X509Certificates.X509Chain chain,
                        System.Net.Security.SslPolicyErrors sslPolicyErrors)
    {
        return true; // **** Always accept
    };

从这里片断: http://www.west-wind.com/weblog/posts/2011/Feb/11/HttpWebRequest-and-Ignoring-SSL-Certificate-Errors



Answer 4:

还有就是短委托的解决方案:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 


Answer 5:

提及已取得之前.NET 4.5的特性上访问其请求ServicePointManager不可用。

下面是.NET 4.0的代码,就可以访问到ServicePoint在每个请求的基础。 它不会给你访问的每个请求的回调,但它应该让你了解这个问题的更多细节。 刚刚访问scvPoint.Certificate (或ClientCertificate如果你喜欢)的属性。

WebRequest request = WebRequest.Create(uri);

// oddity: these two .Address values are not necessarily the same!
//  The service point appears to be related to the .Host, not the Uri itself.
//  So, check the .Host vlaues before fussing in the debugger.
//
ServicePoint svcPoint = ServicePointManager.FindServicePoint(uri);
if (null != svcPoint)
{
    if (!request.RequestUri.Host.Equals(svcPoint.Address.Host, StringComparison.OrdinalIgnoreCase))
    {
        Debug.WriteLine(".Address              == " + request.RequestUri.ToString());
        Debug.WriteLine(".ServicePoint.Address == " + svcPoint.Address.ToString());
    }
    Debug.WriteLine(".IssuerName           == " + svcPoint.Certificate.GetIssuerName());
}


Answer 6:

只是顺便说一句,这是在给定的应用程序,我知道关闭所有证书验证的详细最少方式:

ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;


Answer 7:

基于亚当的回答和Rob的评论我用这个:

ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => certificate.Issuer == "CN=localhost";

该过滤“忽略”有点。 可以根据需要,当然可以添加其他发行人。 这是测试.NET 2.0中,我们需要支持一些遗留代码。



Answer 8:

明确表示...

ServicePointManager.ServerCertificateValidationCallback += new System.Net.Security.RemoteCertificateValidationCallback(CertCheck);

private static bool CertCheck(object sender, X509Certificate cert,
X509Chain chain, System.Net.Security.SslPolicyErrors error)
{
    return true;
}


Answer 9:

添加到撒尼的和blak3r的答案,我已经添加了以下为我的应用程序的启动代码,但在VB:

'** Overriding the certificate validation check.
Net.ServicePointManager.ServerCertificateValidationCallback = Function(sender, certificate, chain, sslPolicyErrors) True

似乎这样的伎俩。



Answer 10:

提示:您还可以用这种方法来跟踪即将到期的证书。 如果您发现该证书即将到期,可以把它固定在这个时间可以节省你的熏肉。 好也为第三方公司 - 对我们来说,这是DHL /联邦快递。 DHL只是让一个证书过期这是感恩节的前3天我们拧起来。 幸运的是,我身边来解决它......这一次!

    private static DateTime? _nextCertWarning;
    private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
    {
        if (error == SslPolicyErrors.None)
        {
            var cert2 = cert as X509Certificate2;
            if (cert2 != null)
            { 
                // If cert expires within 2 days send an alert every 2 hours
                if (cert2.NotAfter.AddDays(-2) < DateTime.Now)
                {
                    if (_nextCertWarning == null || _nextCertWarning < DateTime.Now)
                    {
                        _nextCertWarning = DateTime.Now.AddHours(2);

                        ProwlUtil.StepReached("CERT EXPIRING WITHIN 2 DAYS " + cert, cert.GetCertHashString());   // this is my own function
                    }
                }
            }

            return true;
        }
        else
        {
            switch (cert.GetCertHashString())
            {
                // Machine certs - SELF SIGNED
                case "066CF9CAD814DE2097D367F22D3A7E398B87C4D6":    

                    return true;

                default:
                    ProwlUtil.StepReached("UNTRUSTED CERT " + cert, cert.GetCertHashString());
                    return false;
            }
        }
    }


Answer 11:

几个答案上述工作。 我想,我没有要不断修改代码并没有使我的代码不安全的做法。 因此,我创建了一个白名单。 白名单可以在任何数据存储进行维护。 我使用的配置文件,因为它是一个非常小的列表。

我的代码如下。

ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, error) => {
    return error == System.Net.Security.SslPolicyErrors.None || certificateWhitelist.Contains(cert.GetCertHashString());
};


Answer 12:

而不是增加一个回调ServicePointManager这将在全球范围覆盖证书验证,您可以在HttpClient的本地实例设置回调。 这种做法只会影响使用的HttpClient该实例的调用。

这里是展示了如何为特定服务器忽略证书验证错误可能会在Web API控制器实现的示例代码。

using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

public class MyController : ApiController
{

    // use this HttpClient instance when making calls that need cert errors suppressed
    private static readonly HttpClient httpClient;

    static MyController()
    {
        // create a separate handler for use in this controller
        var handler = new HttpClientHandler();

        // add a custom certificate validation callback to the handler
        handler.ServerCertificateCustomValidationCallback = ((sender, cert, chain, errors) => ValidateCert(sender, cert, chain, errors));

        // create an HttpClient that will use the handler
        httpClient = new HttpClient(handler);
    }

    protected static ValidateCert(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors)
    {

        // set a list of servers for which cert validation errors will be ignored
        var overrideCerts = new string[]
        {
            "myproblemserver",
            "someotherserver",
            "localhost"
        };

        // if the server is in the override list, then ignore any validation errors
        var serverName = cert.Subject.ToLower();
        if (overrideCerts.Any(overrideName => serverName.Contains(overrideName))) return true;

        // otherwise use the standard validation results
        return errors == SslPolicyErrors.None;
    }

}


文章来源: How to ignore the certificate check when ssl