Можно ли определить, используется ли HTTPS-прокси, просто взглянув на сертификат? - PullRequest
3 голосов
/ 19 августа 2010

Поскольку прокси-серверы HTTPS заменят сертификат SSL своим собственным, каковы мои варианты определения того, имеет ли данное соединение HTTPS прокси-сервер в середине?

Я буду использовать эту информацию для определения политики своего приложения, поскольку в некоторых случаях мне нужен 100% сквозной зашифрованный туннель без дешифрования какой-либо третьей стороной.

Еще лучше, если вы подскажете, как определить это с помощью C # в приложении .NET или Silverlight.

Для начала, здесь - это пример метода проверки сертификата с использованием .NET, но я до сих пор не уверен, как его использовать, чтобы определить, какую часть сертификата проверять. Кроме того, я думаю, что ServicePointManger - это скорее "глобальный" класс соединений. Использование этого может быть слишком широким, когда я тестирую одно соединение HTTP, и я не уверен, что ServicePointManager доступен в Silverlight.

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

1 Ответ

4 голосов
/ 19 августа 2010

У вас есть несколько вариантов. Первый вариант - использовать класс ServicePointManager. Вы правы в том, что он управляет всеми точками обслуживания, но вы можете использовать параметр «отправитель» в методе обратного вызова, чтобы различать разные точки обслуживания:

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, поскольку «отправитель» будет 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.
}

Я не мог понять, возможно ли использовать ServicePoint для прокси WCF. Если это невозможно, эта опция не будет работать для 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...