如何在C#中重写ServicePointManager.ServerCertificateValidationCallback时调用默认的证书检查? [英] How to call the default certificate check when overriding ServicePointManager.ServerCertificateValidationCallback in C#?

查看:2709
本文介绍了如何在C#中重写ServicePointManager.ServerCertificateValidationCallback时调用默认的证书检查?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要信任某些自签名证书的应用程序,所以我重写校验回调是这样的:

I need to trust some self-signed certificates in the application, so I override validation callback like this:

ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;
...

public static bool MyRemoteCertificateValidationCallback(
            Object sender,
            X509Certificate certificate,
            X509Chain chain,
            SslPolicyErrors sslPolicyErrors)
{

    if (sslPolicyErrors == SslPolicyErrors.None)
        return true;

    if (IsAprrovedByMyApplication(sender, certificate))  // <-- no matter what the check here is
       return true;
    else 
       return false;  // <-- here I'd like to call the default Windwos handler rather than returning 'false'
}

不过,当有是一些政策失误,而我连接到非认可的应用程序的网站,抛出异常。 这里的问题是,它不同于标准的Windows行为

But when there're some policy errors, and the site I am connecting to is not approved by application, the Exception is thrown. The problem here is that it differs from standard Windows behavior.

考虑一下这个网站: https://www.dscoduc.com/

这是证书未知的发行人,因此不可信。我将它与MMC的地方Copmuter的受信任人(这是Windows 7中)。

It's certificate has an unknown issuer, and therefore untrusted. I have added it with MMC to the Local Copmuter's Trusted People (it's Windows 7).

如果我运行此code无覆盖证书验证回调:

If I run this code without overriding certificate validation callback:

HttpWebRequest http = (HttpWebRequest)HttpWebRequest.Create("https://www.dscoduc.com/");
using (WebResponse resp = http.GetResponse())
{
    using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
    {
        string htmlpage = sr.ReadToEnd();
    }
}

连接成功。 这意味着Windows默认验证器决定信任此证书。

但是,一旦我重写ServerCertificateValidationCallback,我的回调函数调用的 SslPolicyErrors.RemoteCertificateChainErrors 的 和链包含了状态一个元素的 X509ChainStatusFlags.PartialChain 的(其实我也想到会在这里收到任何错误,监守当前证书应该是可信的)

But once I override the ServerCertificateValidationCallback, my callback is called with SslPolicyErrors.RemoteCertificateChainErrors and the chain contains one element with status X509ChainStatusFlags.PartialChain (in fact I would expect to receive no errors here, becuase current cert is supposed to be trusted)

本网站不包含在我的信任列表中,并且不希望从我的回调返回真。 但我不希望返回'假'没有,否则我会得到一个异常:,这显然不是预期的 https://www.dscoduc.com/ ,监守它添加到信任的人商店,以及由Windows批准证书时,回调不覆盖。 所以,我希望Windows采取了默认的验证程序,这个网站。我不想寻找到可信的Windows商店自己去完成所有链元素,因为它已经(希望正确)在Windows中实现的。

This site is not included in my trusted list, and do not want to return 'true' from my callback. But I don't want to return 'false' neither, or I'll get an Exception: "The remote certificate is invalid according to the validation procedure", which is obviously not expected for https://www.dscoduc.com/, becuase it's added to Trusted People store, and is approved by Windows when certificate callback is not overriden. So I want Windows to take the default validation procedure for this site. I don't want to look into Windows Trusted stores myself and go through all the chain elements, because it's already (and hopefully correctly) implemented in Windows.

换句话说,我需要明确信任的网站用户(至极的地方保存在他的设置)approvied,并调用默认的认证检查所有其他人。

有关ServicePointManager.ServerCertificateValidationCallback的默认值为空,因此没有默认的回调让我再打。 我应该怎么称呼这种默认证书处理?

The default value for ServicePointManager.ServerCertificateValidationCallback is null, so there's no 'default' callback for me to call later. How should I call this 'default' certificate handler?

感谢

推荐答案

这是比你想从你的回调中走链不那么困难。

It's less difficult than you think to walk the chain from within your callback.

看一看的http:// MSDN .microsoft.com / EN-US /库/ dd633677(V = EXCHG.80)的.aspx

在code表示样品中检查证书链工作,如果该证书是自签名的,如果是这样,相信它。你可以适应,要接受 PartialChain 代替或为好。你会希望做这样的事情:

The code in that sample examines the certificate chain to work out if the certificate is self-signed and if so, trust it. You could adapt that to accept a PartialChain instead or as well. You'd be looking to do something like this:

if (status.Status == X509ChainStatusFlags.PartialChain ||
    (certificate.Subject == certificate.Issuer &&
     status.Status == X509ChainStatusFlags.UntrustedRoot)
{
    // Certificates with a broken chain and
    // self-signed certificates with an untrusted root are valid. 
    continue;
}
else if (status.Status != X509ChainStatusFlags.NoError)
{
    // If there are any other errors in the certificate chain,
    // the certificate is invalid, so the method returns false.
    return false;
}

另外,检查主题属性:

private static bool CertificateValidationCallBack(
    object sender,
    System.Security.Cryptography.X509Certificates.X509Certificate certificate,
    System.Security.Cryptography.X509Certificates.X509Chain chain,
    System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return certificate.Subject.Contains(".dsoduc.com");
}

这篇关于如何在C#中重写ServicePointManager.ServerCertificateValidationCallback时调用默认的证书检查?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆