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

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

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

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


person telesphore4    schedule 27.07.2009    source источник


Ответы (3)


Если вы используете самозаверяющие сертификаты, то единственные ошибки, которые вы должны ожидать, — это цепная ошибка в корне (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;
}
person MyItchyChin    schedule 27.07.2009

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

person Spencer Ruport    schedule 27.07.2009
comment
+1 полностью согласен. Если вы не можете доверять выдавшему ЦС, то остальная часть сертификата в значительной степени бессмысленна. Если вы не можете использовать настоящие сертификаты, то, как говорит Спенсер, посмотрите, можете ли вы настроить (или уже иметь) свой собственный ЦС, которому вы можете доверять, и оттуда выдавать сертификаты своим пользователям. - person Rob Levine; 27.07.2009
comment
Да, это плохая ситуация, но я пытаюсь сделать ее меньше. По крайней мере, я проверю, что имя в сертификате соответствует указанному URL-адресу. - person telesphore4; 27.07.2009

если вы можете проверить сертификаты, вы можете поместить свою собственную логику проверки в функцию 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; 

}
person Pedro Pacheco    schedule 28.06.2012
comment
Пожалуйста, не делайте этого. Это хуже, чем ничего, потому что создает иллюзию безопасности, но на самом деле таковой не является. Любой может тривиально создать сертификат со строкой CN=www.domain.com в нем. - person Daryl; 02.02.2018