2016-06-16 1 views
1

Я должен проверить несколько сертификатов SSL в не-браузере для соединений HttpRequests и websocket, которые должны запускаться на IOS, Android и Linux. Когда происходит соединение через HTTPS, я получаю массив из X509Certificate2 объектов, где нижний - это сертификат сервера, а самый верхний - корневой СА (надеюсь). В качестве примера, когда я подключаюсь к https://google.com я получаю 3 X509Certificate2 со следующим SubjectName.Name:Как правильно проверить сертификат SSL с помощью X509Certificate2 на Mono и нескольких платформах

  • 0: "CN=google.com, O=Google Inc, L=Mountain View, S=California, C=US"
  • 1: "CN=Google Internet Authority G2, O=Google Inc, C=US"
  • 2: "CN=GeoTrust Global CA, O=GeoTrust Inc., C=US"

мне теперь нужно проверить подтверждение валидации с данной информацией и следующие проверки:

  • цепочки поставок целевых проверки
  • Hostname проверки
  • проверки отзыва сертификатов

То, что я пытался и не понял и не удалось:

Когда я вызываю метод X509Certificate2.Verify() каждого сертификата независимо он возвращает false каждый раз. Я также не понимаю, почему он может вернуть что-нибудь еще, а затем false, потому что проверка происходит независимо. Вместо этого нужно проверить всю цепочку, то есть все сертификаты, насколько я понял теорию.

Затем я использовал X509Chain класс:

foreach (X509Certificate2 cert in allthreecerts) 
    { 
     X509Chain chain = new X509Chain(); 
     X509ChainPolicy chainPolicy = new X509ChainPolicy() 
     { 
      RevocationMode = X509RevocationMode.Offline, 
      RevocationFlag = X509RevocationFlag.EntireChain 
     }; 
     chain.ChainPolicy = chainPolicy; 
     if (!chain.Build(cert)) 
     { 
      foreach (X509ChainElement chainElement in chain.ChainElements) 
      { 
       foreach (X509ChainStatus chainStatus in chainElement.ChainElementStatus) 
       { 
        Debug.WriteLine(chainStatus.StatusInformation); 
       } 
      } 
     } 
    }    

Это печатает RevocationStatusUnknown и OfflineRevocation для каждого сертификата.

Опять же, я не понимаю, почему это должно сработать, так как цепочка строится независимо от каждого сертификата. Не должен ли родительский сертификат выдавать дочерний сертификат до корневого ЦС?

Что мне кажется, мне нужно как-то, но не знаю, как это сделать.

Для проверки отзыва сертификата все клиенты должны предоставить список отзыва сертификатов. Где я могу получить такой список и где его загрузить и указать цепочке для использования этого локального списка?

Та же проблема - проверка цепочки доверия, поскольку последний сертификат должен быть корневым сертификатом и должен быть одним из доверенных корневых центров сертификации клиентов. Поэтому мне приходится загружать, например, все корневые ЦС, которые поставляются с Firefox, и проверить, является ли корневой ЦС одним из них? Каков наилучший способ сделать это?

[Обновить] Я сделал ошибку с копией в примере google.com, где я вставил два одинаковых имени объекта сертификата.

+0

'RevocationMode = X509RevocationMode.Offline' - переключить его на' Online'. Клиент должен иметь локальный кеш CRL/OCSP для успешной проверки отмены в автономном режиме. – Crypt32

+0

Ну, это точка. Я реализую «клиент». Итак, как мне предоставить такой CRL. Это был вопрос, который я задаю. – zlZimon

+1

CRL извлекаются из онлайн-ресурсов. Местоположение CRL указывается в расширении сертификата CRL Distribution Points. Или в разделе «Протокол состояния он-лайн сертификата» в расширении «Доступ к официальным данным». – Crypt32

ответ

1

When a connection via HTTPS happens I receive an array of X509Certificate2 objects where the bottom one is the server certificate and the most top one the root CA (hopefully).

Если вы действительно получили сертификат root c SSL-сервера, тогда сервер SSL настроен неправильно. Он должен вернуть свой серверный сертификат и всю цепочку за исключением корневого сертификата ЦС.

When I call the X509Certificate2.Verify() method on each certificate independently it returns false everytime.

Как указано в documentation метода X509Certificate2.Verify This method builds a simple chain for the certificate and applies the base policy to that chain. Теперь что the base policy я не знаю. Но значение по умолчанию ChainPolicy - RevocationMode = X509RevocationMode.Online. Что касается Моно, источник этого метода можно найти here. Источник реализации Mono X509Chain можно найти: here.

This prints out RevocationStatusUnknown and OfflineRevocation for each certificate.

Что еще нужно напечатать, когда вы указали RevocationMode = X509RevocationMode.Offline и нет CRLs или OCSP ответов в кэше (возможно)?

In order to verify the certificate revocation all clients need to provide a certificate revocation list. Where do I get such a list and where to I load it and tell the chain to use this local list?

Каждый сертификат (кроме сертификата root ca) в цепочке содержит ссылку (или ссылки) в CRL. .NET и, скорее всего, Mono слишком has реализация, которая найдет ссылку на CRL в сертификате, загрузит ее и проверит, не отозван ли сертификат.

The same problem is the Chain-of-trust verification since the last certification should be a root certification and must be one of the clients trusted root CA's. So I have to load, for example, all root CA which are shipped with Firefox and check if the root CA is one of them? What is the best way to do that?

Нет, RevocationFlag = X509RevocationFlag.EntireChain будет делать это для вас с помощью какой-то магазин, который моно использует. Я не знаю, является ли это хранилищем Firefox, но в Linux он имеет свой собственный магазин, и вы можете импортировать сертификаты root ca из магазина Firefox. Проверьте ChainElements и убедитесь сами, какие сертификаты он нашел.

Я бы предположил, что вы создадите цепочку только с сертификатом сервера SSL (так как это проверит все сертификаты в цепочке вверх) с RevocationMode = X509RevocationMode.Online и RevocationFlag = X509RevocationFlag.EntireChain. Я также попытался бы установить свойство X509Chain ExtraStore в список сертификатов, полученных с сервера SSL. После метода Build я бы выделил свойство ChainStatus объекта X509Chain, который представляет собой массив статусов. Я бы выбрал все статусы, которые не установили X509ChainStatus.Status в NoError. Если будет такой статус, я бы бросил и заносил в журнал каждый X509ChainStatus.Status и X509ChainStatus.StatusInformation.

НТН

+0

Это часть, которую я не понимаю. Как может 'X509Certificate2.Verify' построить целую цепочку, если это только один сертификат цепочки? Я установил 'RevocationMode = X509RevocationMode.Online', который дает точные результаты. Свойство «ExtraStore» имеет частный сеттер, поэтому я не могу его установить. Но если CRL загружает/проверяет, а также, если используется хранилище CA, то он должен работать уже (при использовании «RevocationMode = X509RevocationMode.Online')? – zlZimon

+0

Свойство ChainStatus для X509Chain всегда содержит 3 элемента. «PartialChain», «RevocationStatusUnknown» и «OfflineRevocation» даже с 'RevocationMode = X509RevocationMode.Online' – zlZimon

+1

@zlZimon' X509Certificate2.Verify' использует некоторое хранилище сертификатов Mono для поиска сертификатов для создания цепочки. SSL-сервер (не должен) посылает сертификат корневого сафа, так что вы, как клиент, должны строить цепочку против вашего хранилища сертификатов, где вы доверяете сертификатам root ca. Попробуйте tlstest из [этого сайта] (http://www.mono-project.com/docs/faq/security/). Также на этой странице вы найдете 'Обратите внимание, что установка Mono по умолчанию не доверяет никому!', Поэтому вам необходимо вручную загрузить доверенные корневые сертификаты с помощью 'certmgr.exe' или' mozroots.exe'. – pepo

Смежные вопросы