Как добавить доверенный сертификат CA (НЕ сертификат клиента) в HttpWebRequest? - PullRequest
6 голосов
/ 01 марта 2012

Я написал программу на C #, которая использует HttpWebRequest для подключения к HTTPS-сайту.Метод GetResponse() вызывает исключение:

SystemError: Основное соединение было закрыто: не удалось установить доверительные отношения для безопасного канала SSL / TLS.

I 'Я могу подключиться к тому же сайту, используя curl.exe --cacert CAFile.pem.Я хотел бы иметь возможность использовать те же самые доверенные сертификаты CA из программы C #.

Как я могу получить HttpWebRequest для использования этого файла сертификата CA (или X509CertificateCollection, содержащего сертификаты, проанализированные из него)?

Ответы [ 2 ]

5 голосов
/ 09 октября 2012

Попробуйте настроить ваш ServerCertificateValidationCallback для использования этого:

public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
    return true;

    X509Chain privateChain = new X509Chain();
    privateChain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;

    X509Certificate2 cert2 = new X509Certificate2(certificate);
    X509Certificate2 signerCert2 = new X509Certificate2(@"C:\MyCACert.PEM");

    privateChain.ChainPolicy.ExtraStore.Add(signerCert2);       
    privateChain.Build(cert2);

    bool isValid = true;

    foreach (X509ChainStatus chainStatus in privateChain.ChainStatus)
    {
        if (chainStatus.Status != X509ChainStatusFlags.NoError)
        {
            isValid = false;
            break;
        }
    }

    return isValid;
}

У меня не было возможности проверить это, поэтому сообщите мне, если у вас возникнут какие-либо ошибки, и я при необходимости изменю ответ.

1 голос
/ 13 октября 2012

В конечном итоге я решил написать класс, реализующий ICertificatePolicy с настраиваемой логикой проверки:

private X509CertificateCollection   _certs;
private ICertificatePolicy          _defaultPolicy;

public bool CheckValidationResult(ServicePoint svcPoint, X509Certificate cert, WebRequest req, int problem)
{
    if ((_defaultPolicy != null) && _defaultPolicy.CheckValidationResult(svcPoint, cert, req, problem))
    {
        return true;
    }

    foreach (X509Certificate caCert in _certs)
    {
        if (caCert.Equals(cert))
        {
            return true;
        }
    }

    return false;
}

(проверка ошибок опущена для краткости.)

_defaultPolicy можно установить на ServicePointManager.CertificatePolicy, чтобы разрешить использование хранилища сертификатов по умолчанию в дополнение к настраиваемым сертификатам.

_certs содержит дополнительные сертификаты. Он генерируется путем анализа файла PEM и вызова _certs.Add(new X509Certificate(Convert.FromBase64String(base64cert)));

CertificatePolicy устарел ServerCertificateValidationCallback, но мне нужно было поддерживать старую версию .NET.

...