Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Программирование .Net: что проверять на самозаверяющем сертификате SSL

Автор вопроса: telesphore4Ответов: 3

Я не могу заставить пользователей создавать настоящие сертификаты для своих серверов, но я хотел бы выполнить некоторые проверки безопасности. Итак, следующее слишком легкое, потому что, как я его читал, нет проверки сертификатов.

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

Что вы рекомендуете, чтобы клиенты проверяли сертификат x509? Учитывая, что я использую язык .NET (c#/f#).

ssl-certificate

Ответы

Ответ 1 · рейтинг 6 · MyItchyChin

Если вы используете самозаверяющие сертификаты, то единственные ошибки, которые вы должны ожидать, - это цепная ошибка в корне (Cert. Issuer). Я бы предложил что-то вроде этого, которое специально ловит эту цепочку ошибок и позволяет пропустить все другие ошибки.

ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(
    ValidateRemoteCertificate
);

private static bool ValidateRemoteCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors )
{
    string trustedIssuer = "CN=www.domain.com";
    string trustedDomain = "CN=www.domain.com";
    bool policyErr = false;

    switch (policyErrors)
    {
        case SslPolicyErrors.None:
            policyErr |= false;
            break;
        case SslPolicyErrors.RemoteCertificateChainErrors:
            bool chainErr = false;
            foreach (X509ChainStatus status in chain.ChainStatus)
            {
                switch (status.Status)
                {
                    case X509ChainStatusFlags.NoError:
                        chainErr |= false;
                        break;
                    case X509ChainStatusFlags.UntrustedRoot:
                        if (certificate.Subject != trustedDomain || certificate.Issuer != trustedIssuer)
                            chainErr |= true;
                        else
                            chainErr |= false;
                        break;
                    default:
                        chainErr |= true;
                        break;
                }
            }
            policyErr |= chainErr;
            break;
        default:
            policyErr |= true;
            break;
    }

    return !policyErr;
}

Ответ 2 · рейтинг 4 · Spencer Ruport

Если вы не можете заставить клиентов создавать настоящие сертификаты, вы должны хотя бы попытаться заставить их создавать сертификаты с использованием вашего сервера. Затем вы можете проверить, действителен ли сертификат или, по крайней мере, сертификат вашего ЦС, потому что вы будете знать, был ли скомпрометирован ваш ЦС. Если вы доверяете всем без исключения центрам сертификации, проверять действительно нечего.

Ответ 3 · Pedro Pacheco

если вы можете проверить сертификаты, вы можете поместить свою собственную логику проверки в функцию ValidateRemoteCertificate

System.Net.ServicePointManager.ServerCertificateValidationCallback += (a, b, c, d) =>
{
     return ValidateRemoteCertificate(a, b, c, d);
};

private static bool ValidateRemoteCertificate(object sender, X509Certificate certificate,
            X509Chain chain, SslPolicyErrors policyErrors)
{
            if (certificate.Subject.Equals("CN=www.domain.com"))
                return true;
            else
               return policyErrors == SslPolicyErrors.None;

}

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы