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

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

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

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

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

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


person halfbit    schedule 19.08.2010    source источник
comment
Как ваше приложение устанавливает безопасное соединение? WCF? HTTPWebRequest?   -  person Andy Wilson    schedule 19.08.2010
comment
Я ищу общее решение, которое будет охватывать все методы связи на основе .NET. Да, я использую WCF и HTTPWebRequest.   -  person halfbit    schedule 19.08.2010


Ответы (1)


У вас есть несколько вариантов. Первый вариант — использовать класс 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;
}
person Andy Wilson    schedule 19.08.2010
comment
Спасибо, но мне все еще нужно выяснить, что делать с сертификатом, когда я его получу. Нет ли общего способа обнаружить прокси через сертификат? Должен ли я жестко кодировать ожидаемую строку открытого ключа в своем приложении? Также я не уверен, что этот подход работает в Silverlight... Я сомневаюсь, что смогу получить доступ к ServicePointManager в песочнице SLI. - person halfbit; 19.08.2010
comment
Подход DoesRequestUseProxy не будет работать, если на брандмауэре используется WCCP. WCCP — это прозрачный прокси, не требующий настройки клиента. BlueCoat — это пример продукта, который будет взаимодействовать со всеми данными, поступающими от брандмауэра, и прозрачно проксировать HTTPS-трафик. Именно по этой причине я считаю единственным универсальным методом анализ самого сертификата. - person halfbit; 19.08.2010
comment
Я обновил свой ответ, чтобы показать, как определить, использует ли веб-запрос прокси. К сожалению, я только что подтвердил, что ни один код в моем ответе не будет работать в Silverlight. - person Andy Wilson; 19.08.2010
comment
Спасибо за проверку подхода Silverlight :) - person halfbit; 19.08.2010