是否可以通过查看证书来确定是否正在使用HTTPS代理?

时间:2010-08-19 14:59:34

标签: c# silverlight proxy https certificate

由于HTTPS代理会将SSL证书替换为自己的SSL证书,我有哪些选择来确定给定的HTTPS连接是否在中间有代理?

我将使用此信息来确定我的应用程序策略,因为在某些情况下我需要100%端到端加密隧道而不会被任何第三方解密。

如果你能告诉我如何通过.NET应用程序或Silverlight中的C#来确定这一点,那就更好了。

对于初学者,here是使用.NET验证证书的示例方法,但我仍然不确定如何使用它来确定要验证的证书的哪个部分。另外,我认为ServicePointManger更像是一个“全局”连接类。当我测试单个HTTP连接时,使用它可能过于宽泛,而且我不确定Silverlight中是否有ServicePointManager可用。

http://msdn.microsoft.com/en-us/library/bb408523.aspx

1 个答案:

答案 0 :(得分:4)

你有几个选择。第一个选项是使用ServicePointManager类。你是正确的,因为它管理所有服务点,但您可以使用回调方法中的“sender”参数来区分不同的服务点:

void SomeMethod()
{
    ServicePointManager.ServerCertificateValidationCallback += 
        ValidateServerCertificate;

    var url = "https://mail.google.com/mail/?shva=1#inbox";
    var request = (HttpWebRequest)WebRequest.Create(url);
    request.GetResponse();
}

private static bool ValidateServerCertificate(object sender, 
        X509Certificate certificate, X509Chain chain, 
        SslPolicyErrors sslpolicyerrors)
{
    if(sender is HttpWebRequest)
    {
        var request = (HttpWebRequest) sender;
        if(request.RequestUri.ToString() == "https://mail.google.com/mail/?shva=1#inbox")
        {
            return (certificate.GetPublicKeyString() == "The public key string you expect");
        }
    }
    return true;
}

此选项适用于手动创建的HttpWebRequest和WCF创建的请求,因为“sender”将是两者的HttpWebRequest。我不确定“发件人”是否只是一个HttpWebRequest。

第二个选项是直接从服务点获取证书:

void SomeMethod()
{
    ServicePointManager.ServerCertificateValidationCallback += 
        ValidateServerCertificate;

    var url = "https://mail.google.com/mail/?shva=1#inbox";
    var request = (HttpWebRequest)WebRequest.Create(url);
    request.GetResponse();

    var serverCert = request.ServicePoint.Certificate;
    // Validate the certificate.
}

我无法弄清楚是否有可能获得WCF代理使用的ServicePoint。如果不可能,则此选项对WCF不起作用。除此之外,最大的区别在于,如果证书验证失败,第一个选项会阻止连接,而第二个方法在连接完成之后才会进行验证。

如果您只需要确定请求是否要通过代理:

var httpRequest = (HttpWebRequest)WebRequest.Create("someurl");
var isUsingProxy = DoesRequstUseProxy(request);

bool DoesRequestUseProxy(HttpWebRequest request)
{
    if(request.Proxy == null)
    {
        return false;
    }

    return request.Proxy.GetProxy(request.RequestUri) != request.RequestUri;
}