Метод X509Certificate2.Verify () всегда возвращает false для действительного сертификата

Я использую смарт-карту для аутентификации.

SecurityTokenService (служба аутентификации) размещается только на моем компьютере. Смарт-карта имеет действующий сертификат, и ее корневой сертификат также установлен в хранилище локального компьютера на моем компьютере.

Когда я использую метод X509Certificate2.Verify для проверки сертификата в моей службе, он всегда возвращает false.

Может ли кто-нибудь помочь мне понять, почему метод X509Certificate2.Verify () всегда возвращает false?

Примечание: я использовал X509Chain и проверил все флаги (X509VerificationFlags.AllFlags). Когда я создаю чанин, он возвращает true с ChainStatus как RevocationStatusUnknown.


РЕДАКТИРОВАТЬ 1:

Я заметил, что метод X509Certificate2.Verify() возвращает true, если я напишу этот код в приложении Windows Form. Он возвращает false только в коде стороны службы. Почему так? Удивительно, но факт!


person Learner    schedule 13.04.2012    source источник


Ответы (2)


Значения X509VerificationFlags являются подавляемыми, поэтому указание X509VerificationFlags.AllFlags фактически не позволяет Build возвращать false в большинстве ситуаций.

Ответ RevocationStatusUnknown кажется особенно актуальным. Независимо от того, какой сертификат он сообщает, что невозможно проверить, он не может быть отозван. Метод Verify можно смоделировать как

public bool Verify()
{
    using (X509Chain chain = new X509Chain())
    {
        // The defaults, but expressing it here for clarity
        chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
        chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
        chain.ChainPolicy.VerificationTime = DateTime.Now;
        chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;

        return chain.Build(this);
    }
}

Что, поскольку он не утверждает X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown или X509VerificationFlags.IgnoreEndRevocationUnknown при запросе X509RevocationMode, отличного от None, не выполняется.

Во-первых, вы должны определить, какие сертификаты в цепочке не работают:

using (X509Chain chain = new X509Chain())
{
    // The defaults, but expressing it here for clarity
    chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
    chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
    chain.ChainPolicy.VerificationTime = DateTime.Now;

    chain.Build(cert);

    for (int i = 0; i < chain.ChainElements.Count; i++)
    {
        X509ChainElement element = chain.ChainElements[i];

        if (element.ChainElementStatus.Length != 0)
        {
            Console.WriteLine($"Error at depth {i}: {element.Certificate.Subject}");

            foreach (var status in element.ChainElementStatus)
            {
                Console.WriteLine($"  {status.Status}: {status.StatusInformation}}}");
            }
        }
    }
}

Если вы посмотрите на какой-либо сбойный сертификат в Windows CertUI (дважды щелкните .cer в проводнике или в оснастке Certificates MMC), найдите поле с именем «CRL Distribution Points». Это URL-адреса, которые будут получены во время выполнения. Возможно, в вашей системе есть ограничение на исходящие данные, которое не позволяет запрашивать эти конкретные значения. Вы всегда можете попробовать отправить веб-запрос от своего веб-сервиса, чтобы узнать, может ли он получить URL-адреса без контекста нахождения в подсистеме сертификатов.

person bartonjs    schedule 06.07.2016

Я думаю, проблема связана с прокси-сервером и некоторыми настройками безопасности в моей организации. Я не могу указать вескую причину, почему он работает из клиента WinForm, а почему нет из кода, размещенного под IIS.

Но я хочу сообщить читателям, что метод Verify() работал и с серверным кодом, когда я размещал службу в IIS, работающую на машине за пределами моего обычного домена! Таким образом, вы можете проверить, не мешают ли вам настройки брандмауэра вашего домена / организации.

person Learner    schedule 30.04.2012
comment
Клиент WinForm будет работать под учетными данными вашего домена, а в IIS учетные данные будут другими. Может быть, это одна из причин. Попробуйте включить проверку подлинности Windows в IIS и посмотрите, не изменится ли это. - person Deepansh Gupta; 30.04.2012
comment
Веб-приложение работает под учетной записью NETWORK SERVICE. У этого пользователя есть доступ к сертификату. Но да, ваша точка зрения верна; это часто является причиной отказа метода Verify () из веб-приложения IIS. - person Learner; 30.04.2012