2012-05-23 3 views
4

я обнаружил, что, когда я использую HttpWebRequest для установления соединения SSL \ TLS, требуется возле 30s при вызовеСоздание SSL TLS соединение (X509Chain.Build()) занимает слишком много времени

request.GetRequestStream() 

, когда я включен трассировку с StackTrace включена, я обнаружил, что 2s идет найти никудышный, поэтому я отключил его в app.config:

<system.net> 
<defaultProxy enabled="false" useDefaultCredentials="false"> 
    <proxy/> 
    <bypasslist/> 
    <module/> 
</defaultProxy> 
</system.net> 

Следующая точка, которая принимает рядом 28s был в

at System.Net.Security.SecureChannel.AcquireClientCredentials(Byte[]& thumbPrint) 

После осмотра тела метода я нашел вызов X509Chain.Build(), и для создания цепочки сертификатов потребовалось около 25 секунд.

Интересно, что при создании нового HttpWebReqest и повторных попыток (без перезагрузки приложения) для выполнения запроса потребовалось несколько мс.

Может ли кто-нибудь предложить, что делать? Запрос кэширования не является вариантом, он должен быть быстрым от запуска приложения.

Обновление:

Я нашел вызов, который принимает 30s в X509Chain.BuildChain(), это:

if (!CAPISafe.CertGetCertificateChain(hChainEngine, pCertContext, ref pTime, invalidHandle, ref cert_chain_para, dwFlags, IntPtr.Zero, ref ppChainContext)) 

Метод объявлен в CAPISafe как:

[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
internal static extern bool CertGetCertificateChain([In] IntPtr hChainEngine, [In] SafeCertContextHandle pCertContext, [In] ref System.Runtime.InteropServices.ComTypes.FILETIME pTime, [In] SafeCertStoreHandle hAdditionalStore, [In] ref CAPIBase.CERT_CHAIN_PARA pChainPara, [In] uint dwFlags, [In] IntPtr pvReserved, [In, Out] ref SafeCertChainHandle ppChainContext); 

Итак, это функция Crypto API CertGetCertificateChain Все еще не знаю, что делать дальше ...

Update:

Я попытался не отключить CRL и OCSP проверки, до сих пор никакого эффекта:

  1. Добавить в App.config

    <runtime> 
        <generatePublisherEvidence enabled="false"/> 
    </runtime> 
    
  2. машина шириной: Панель управления -> Свойства обозревателя -> Дополнительно -> В разделе безопасности, снимите флажок Проверить вариант отзыва сертификата издателя

  3. В реестре:

    [HKEY_USERS \ S-1-5-20 \ Software \ Microsoft \ Windows \ CurrentVersion \ Провайдеры WinTrust \ Trust \ Software Publishing] "государство" = DWORD: 00023e00

+0

FWIW, # 1 отключает создание доказательств для приложения, основанное на сигнатуре Authenticode приложения, если оно есть. # 2 отключает проверку отзыва подлинности аутентификации для подписи Authenticode (используется только в редких случаях). Ни один из них не применяется к проверкам отзыва сертификатов клиента SSL. – EricLaw

ответ

3

Наконец-то я нашел корни проблемы. Я включил CAPI2 регистрацию в журнале событий и нашел NetworkTimeoutException при попытке загрузить список доверия сертификатов от:

http://www.download.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootstl.cab

Таким образом, это был вопрос брандмауэра. Вы можете прочитать blogpost о процессе и методах расследования.

+0

У одного из разработчиков Microsoft есть сообщение об этом: https://blogs.msdn.microsoft.com/alejacma/2011/09/27/big-delay-when-calling-sslstream-authenticateasclient/ – Aidin

3

Как правило, строительство пути подразумевает строительство пути, и для этого требуется проверка того, был ли какой-либо из сертификатов revoked с момента их выдачи.

Чтобы проверить текущий статус отзыва, вам нужна обновленная информация от CRL или ответчика OCSP.Если корректный CRL не указан явно во время настройки запроса проверки пути, многие библиотеки попытаются извлечь его (обычно через Интернет), если URL-адрес для CRL указан в "CRL Distribution Points" extension.

Это может занять некоторое если ваша сеть медленная, путь длинный, или CRL являются большими. Возможно, это то, что так долго в вашем случае. Поскольку он работает быстро после первого раза, я предполагаю, что некоторые большие CRL загружаются во время первой попытки и кэшируются для последующего использования.

Кроме того, библиотека мощь автоматически связаться с OCSP responder если она рекламируется в "Authority Information Access" extension. Однако, некоторые библиотеки требуют конкретной конфигурации для использования OCSP, или предпочесть его на CRL.

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

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

+0

Благодарим за сообщение. Похоже, что это не вариант, я могу видеть из кода, экземпляр X509Chain создан: 'с X509Chain цепи = новый X509Chain { ChainPolicy = {RevocationMode = X509RevocationMode.NoCheck, VerificationFlags = X509VerificationFlags.IgnoreInvalidName} } ; ' Кроме того, сертификаты имеют пустой список OCSP. – hkurabko

+0

Теперь, я обнаружил, что даже с отключенной CRL и OCSP проверки приложения пытается подключиться к этому IP-адресов: 8.26.222.254:http 199.93.57.254:http 206.33.54.126:http 4.26.235.254:http 8.27.7.126 : http Итак, возможно, вы правы. Но где он должен быть отключен? И действительно ли это причина для его отключения? – hkurabko

+0

Отъезд. В цепочке нет сертификатов с точкой распространения CRL, а у несертификатов есть какой-либо OCSP в списке. Итак, вопрос в том, где и почему он соединяется? – hkurabko