X509Certificate2.Verify() всегда возвращает false
Перед лицом действительно странной проблемы X509Certificate2.Verify() возвращает false для действительного сертификата. Возможно, кто-то уже сталкивался с этим странным сценарием раньше и может пролить свет на него.
Я использую openssl для генерации клиентских сертификатов в целях тестирования. Я создаю Root CA и генерирую клиентский сертификат на основе этого Root CA и добавляю Root CA в его цепочку.
Я загружаю Root CA и Client Cert в локальное хранилище сертификатов, и там все нормально, но когда я загружаю его из своего кода NUnit для проверки X509Certificate2.Verify() всегда возвращает false.
Вот код для загрузки сертификата из магазина:
X509Store store = new X509Store(StoreName.My);
string thumbprint = "60 d1 38 95 ee 3a 73 1e 7e 0d 70 68 0f 2d d0 69 1e 9a eb 72";
store.Open(OpenFlags.ReadOnly);
var mCert = store.Certificates.Find(
X509FindType.FindByThumbprint,
thumbprint,
true
).OfType<System.Security.Cryptography.X509Certificates.X509Certificate>().FirstOrDefault();
if(mCert != null)
{
var testClientCert = new X509Certificate2(mCert);
}
Вот сертификат клиента, который я только что сгенерировал: (URL CRL доступен с моего локального компьютера правильно)
-----BEGIN CERTIFICATE-----
MIIC7jCCAlegAwIBAgIBATANBgkqhkiG9w0BAQUFADBtMR0wGwYDVQQKExRWaXRh
bEhlYWx0aCBTb2Z0d2FyZTElMCMGA1UECxMcVml0YWxIZWFsdGggU29mdHdhcmUg
Um9vdCBDQTElMCMGA1UEAxMcVml0YWxIZWFsdGggU29mdHdhcmUgUm9vdCBDQTAe
Fw0xNTAyMjcwODQ2MzNaFw0xNjAyMjcwODQ2MzNaMEUxHTAbBgNVBAoTFFZpdGFs
SGVhbHRoIFNvZnR3YXJlMREwDwYDVQQLEwhQbGF0Zm9ybTERMA8GA1UEAxMIVGVz
dFVzZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOkfyjX0PSnRYrBbCC8u
rw7IiFdAUj6frPKEmt0TLAR/4g+NazKdGjRRqxE9mNwX/2zGhIcucfGDVwPtOtiV
opicQEzGiSQkvAc+473MN5D6j3XtBYblALMeMyEYoh3LnHO4K+6kV6XE4BXV/2lV
mAVgXGkZzaayd40DLvg48vPlAgMBAAGjgcUwgcIwCQYDVR0TBAIwADARBglghkgB
hvhCAQEEBAMCB4AwCwYDVR0PBAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMCMDEG
CWCGSAGG+EIBDQQkFiJPcGVuU1NMIENlcnRpZmljYXRlIGZvciBTU0wgQ2xpZW50
ME0GA1UdHwRGMEQwQqBAoD6GPGh0dHA6Ly9wbGF0Zm9ybWRhc2hib2FyZC5ubC52
aXRhbGhlYWx0aC5sb2NhbC9wb3J0YWwvY3JsLmNybDANBgkqhkiG9w0BAQUFAAOB
gQBXYSmZaVu6vnyl94SO4qpNOutsUm4p7fQHehljhZ+aRrXE10rivWCt4g0k961E
PDsp4J0DR6uth6et42pBp8v2gFIGSQY/F7NhmOAsOJvM7z0oIBxMLcclIDTygbRp
KjZZpNjvf+YJasbidosiL4VSeRiCZ+HPzvKDb3wNeafoZA==
-----END CERTIFICATE-----
И вот файл CRL, который загружается при доступе к нему из браузера:
-----BEGIN X509 CRL-----
MIIBMjCBnDANBgkqhkiG9w0BAQUFADBtMR0wGwYDVQQKExRWaXRhbEhlYWx0aCBT
b2Z0d2FyZTElMCMGA1UECxMcVml0YWxIZWFsdGggU29mdHdhcmUgUm9vdCBDQTEl
MCMGA1UEAxMcVml0YWxIZWFsdGggU29mdHdhcmUgUm9vdCBDQRcNMTQwODA3MTQz
OTIyWhcNMTQwOTA2MTQzOTIyWjANBgkqhkiG9w0BAQUFAAOBgQA8MSxAorbxpdDm
1IA2Aqjb/OkZydua1Tm5k5KtHknI4zyYPZb3GzO0eRygpKBSAqtYkxDI6eCv6xgf
+anXT56md+cPGZ+2YvSicxqwP2GL2kymc9mVMTiQieioS1/7apjCIjZEgWxqf3Up
zvy/kNQRg3lII8hYu0idGs9byKZJFQ==
-----END X509 CRL-----
1 ответ
Согласно X509Certificate2.Verify документация
Этот метод создает простую цепочку для сертификата и применяет базовую политику к этой цепочке. Если вам нужна дополнительная информация о сбое, проверьте сертификат непосредственно с помощью объекта X509Chain.
Поэтому я бы попытался построить цепочку, используя этот код (замените метод Log вашей собственной реализацией, я использовал Console.Writeline)
X509Chain chain = new X509Chain();
try
{
var chainBuilt = chain.Build(testClientCert );
Log(string.Format("Chain building status: {0}", chainBuilt));
if (chainBuilt == false)
foreach (X509ChainStatus chainStatus in chain.ChainStatus)
Log(string.Format("Chain error: {0} {1}", chainStatus.Status, chainStatus.StatusInformation));
}
catch (Exception ex)
{
Log(ex.ToString());
}
Этот код расскажет вам причину, по которой сертификат не может быть проверен. Если вам нужно настроить политику цепочки, установите chain.ChainPolicy
свойство т.е.
chain.ChainPolicy = new X509ChainPolicy()
{
RevocationMode = X509RevocationMode.NoCheck,
VerificationFlags = X509VerificationFlags.IgnoreNotTimeValid,
UrlRetrievalTimeout = new TimeSpan(0, 1, 0)
};