2012-05-30 6 views
47

Мой клиент сообщил мне о проблемах с их SSL и Internet Explorer. Они сказали, что получают проблемы с доверием при обращении к URL-адресу.Запрос был прерван: не удалось создать защищенный канал SSL/TLS

Я обращаюсь к JSON через HTTPS. Веб-сайт находится на одном сервере, и я использую консольное приложение на своей локальной машине. Я пытаюсь обойти SSL-сертификат, однако мой код все еще не работает.

Могу ли я изменить HttpWebRequest, чтобы исправить эту проблему?

Я получаю эту ошибку, используя этот код:

// You must change the URL to point to your Web server. 
     HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); 
     req.Method = "GET"; 
     req.AllowAutoRedirect = true; 

     // allows for validation of SSL conversations 
     ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 


     WebResponse respon = req.GetResponse(); 
     Stream res = respon.GetResponseStream(); 

     string ret = ""; 
     byte[] buffer = new byte[1048]; 
     int read = 0; 
     while ((read = res.Read(buffer, 0, buffer.Length)) > 0) 
     { 
      //Console.Write(Encoding.ASCII.GetString(buffer, 0, read)); 
      ret += Encoding.ASCII.GetString(buffer, 0, read); 
     } 
     return ret; 
+0

вы самозаверяющие сертификаты? –

+0

Нет, клиент говорит Комодо. –

+0

Возможный дубликат [Запрос был прерван: не удалось создать безопасный канал SSL/TLS] (https://stackoverflow.com/questions/2859790/the-request-was-aborted-could-not-create-ssl-tls- secure-channel) –

ответ

18

Я включил протоколирование, используя этот код:

http://blogs.msdn.com/b/dgorti/archive/2005/09/18/471003.aspx

Журнал был в папке bin/отладки (я был в режиме отладки для моей консольного приложения). Вам нужно добавить тип протокола безопасности как SSL 3

Я получил несоответствие алгоритма в журнале. Вот мой новый код:

 // You must change the URL to point to your Web server. 
     HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); 
     req.Method = "GET"; 
     ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; 


     // Skip validation of SSL/TLS certificate 
     ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 


     WebResponse respon = req.GetResponse(); 
     Stream res = respon.GetResponseStream(); 

     string ret = ""; 
     byte[] buffer = new byte[1048]; 
     int read = 0; 
     while ((read = res.Read(buffer, 0, buffer.Length)) > 0) 
     { 
      Console.Write(Encoding.ASCII.GetString(buffer, 0, read)); 
      ret += Encoding.ASCII.GetString(buffer, 0, read); 
     } 
     return ret; 
+7

Важно отметить, что на SSLv3 обнаружена ошибка (http://security.stackexchange.com/a/70724), и большинство реализаций больше не разрешат ее. Вместо этого вы должны использовать 'SecurityProtocolType.Tls12'. – douglaslps

+6

Имейте в виду, что использование этого решения подразумевает, что * любой сертификат сервера будет принят как действительный (поскольку 'ServerCertificateValidationCallback' всегда возвращает true) –

6

Это может быть вызвано несколькими вещами (скорее всего, наименее вероятно):

  1. сертификат SSL между сервером сомнителен самая клиент. Самая простая проверка - указать браузер по URL-адресу и посмотреть, есть ли значок значка SSL. Если вы получаете сломанный замок, значок, нажмите на нее, чтобы увидеть, что вопрос:

    1. Просроченные даты - получить новый сертификат SSL
    2. Имя не соответствует - убедитесь, что ваш URL использует тот же сервер имя в качестве сертификата.
    3. Не подписан доверенным органом - покупайте сертификат у такого органа, как Verisign, или добавьте сертификат в хранилище доверенных сертификатов клиента.
    4. В тестовых средах вы можете обновить средство проверки сертификатов, чтобы пропустить проверки доступа. Не делайте этого в производстве.
  2. Для работы сервера требуется SSL-сертификат клиента - в этом случае вам необходимо будет обновить свой код, чтобы подписать запрос с сертификатом клиента.

+1

Все хорошее, за исключением последнего пункта. Сертификат клиента не используется для подписания запроса, он предоставляется в рукопожатии, поэтому он должен быть доступен для транспорта до открытия соединения. Как это делается в Javascript, остается как упражнение для читателя ;-) – EJP

+0

Как я могу подписаться с сертификатом клиента? Я добавил ServicePointManager.ServerCertificateValidationCallback = delegate {return true; }, но это все еще дает мне ошибку. –

+0

Ваш комментарий «требуется SSL-сертификат клиента» помог мне взглянуть на фактический сертификат, который я отправлял ... и, таким образом, мой новый ответ с этим вопросом. «Дух» сейчас, но сейчас несколько часов назад! Thx – granadaCoder

105

мне пришлось включить другие версии протокола безопасности, чтобы решить эту проблему:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls 
     | SecurityProtocolType.Tls11 
     | SecurityProtocolType.Tls12 
     | SecurityProtocolType.Ssl3; 
+0

Потеряно 2 дня, чтобы реализовать его, декомпилировал класс HttpWebRequest, но помог только переход на TLS. –

+0

превосходный ответ +1 – Hitesh

+2

Уфф, я почти потерял сознание! Это был недостающий кусок! – jsicary

10

Подобно an existing answer но в PowerShell:

[System.Net.ServicePointManager]::SecurityProtocol = ` 
[System.Net.SecurityProtocolType]::Tls11 -bor 
[System.Net.SecurityProtocolType]::Tls12 -bor ` 
[System.Net.SecurityProtocolType]::Tls -bor ` 
[System.Net.SecurityProtocolType]::Ssl3 

Затем вызова Invoke-WebRequest должен работать.

получил это от анонимных обратной связи, хорошее предложение: простого способа, чтобы написать это было бы:

[System.Net.ServicePointManager]::SecurityProtocol = @("Tls12","Tls11","Tls","Ssl3") 

Найден этим фантастический и связанный столб Jaykul: Validating Self-Signed Certificates From .Net and PowerShell

+0

Ответы перемещаются в зависимости от того, как вы их сортируете, и по умолчанию сколько голосов у них есть. Рассмотрите возможность ссылки на другой ответ его автора. – Litty

+0

woot благодарит вас за этот пост ... Я был озадачен настройкой типа протокола. –

0

Я нашел тип сертификата и вступает в игру.

У меня был сертификат, который был:

(ниже выход был в ММС, свойства сертификата)

цифровой подписи, ключ шифрования (a0)

(ниже выход был из мой C# код ниже)

X509Extension.X509KeyUsageExtension.KeyUsages = 'KeyEncipherment, DigitalSignature' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.CrlSign = 'False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DataEncipherment = 'False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DecipherOnly = 'False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DigitalSignature = 'Правда' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.EncipherOnly = 'False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyAgreement = 'False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyCertSign = 'False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyEncipherment = 'Правда' X509KeyUsageExtension.KeyUsages.X509KeyU sageFlags.None = 'False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.NonRepudiation = 'False'

выше сделал не работу.

===============================

Затем еще один сертификат с:

(ниже выход был в ММС, свойства сертификата)

подписание сертификата, офф-лайн CRL Подписание, CRL подписи (06)

(ниже выход был из моего C# код ниже)

X509Extension.X509KeyUsageExtension.KeyUsages = 'CrlSign, KeyCertSign' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.CrlSign = 'Правда ' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DataEncipherment =' False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DecipherOnly =» False» X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DigitalSignature = 'False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.EncipherOnly = 'False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyAgreement = 'False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyCertSign = 'Правда ' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyEncipherment =' False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.None = 'False' X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.NonRepudiation = 'False'

и сделали работу

ниже код позволит вам проверить ваш сертификат клиента

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Security.Cryptography; 
using System.Security.Cryptography.X509Certificates; 
using System.Text; 

namespace MyNamespace 
{ 
    public static class SecurityShower 
    { 
     public static void ShowHttpWebRequest(System.Net.HttpWebRequest hwr) 
     { 
      StringBuilder sb = new StringBuilder(); 
      if (null != hwr) 
      { 
       sb.Append("-----------------------------------------------HttpWebRequest" + System.Environment.NewLine); 
       sb.Append(string.Format("HttpWebRequest.Address.AbsolutePath='{0}'", hwr.Address.AbsolutePath) + System.Environment.NewLine); 
       sb.Append(string.Format("HttpWebRequest.Address.AbsoluteUri='{0}'", hwr.Address.AbsoluteUri) + System.Environment.NewLine); 
       sb.Append(string.Format("HttpWebRequest.Address='{0}'", hwr.Address) + System.Environment.NewLine); 

       sb.Append(string.Format("HttpWebRequest.RequestUri.AbsolutePath='{0}'", hwr.RequestUri.AbsolutePath) + System.Environment.NewLine); 
       sb.Append(string.Format("HttpWebRequest.RequestUri.AbsoluteUri='{0}'", hwr.RequestUri.AbsoluteUri) + System.Environment.NewLine); 
       sb.Append(string.Format("HttpWebRequest.RequestUri='{0}'", hwr.RequestUri) + System.Environment.NewLine); 

       foreach (X509Certificate cert in hwr.ClientCertificates) 
       { 
        sb.Append("START*************************************************"); 
        ShowX509Certificate(sb, cert); 
        sb.Append("END*************************************************"); 
       } 
      } 

      string result = sb.ToString(); 
      Console.WriteLine(result); 
     } 

     public static void ShowCertAndChain(X509Certificate2 cert) 
     { 
      X509Chain chain = new X509Chain(); 
      chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; 
      chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline; 
      chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; 

      ////chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreCtlSignerRevocationUnknown && 
      ////X509VerificationFlags.IgnoreRootRevocationUnknown && 
      ////X509VerificationFlags.IgnoreEndRevocationUnknown && 
      ////X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown && 
      ////X509VerificationFlags.IgnoreCtlNotTimeValid; 

      chain.Build(cert); 

      ShowCertAndChain(cert, chain); 
     } 

     public static void ShowCertAndChain(X509Certificate cert, X509Chain chain) 
     { 
      StringBuilder sb = new StringBuilder(); 
      if (null != cert) 
      { 
       ShowX509Certificate(sb, cert); 
      } 

      if (null != chain) 
      { 
       sb.Append("-X509Chain(Start)-" + System.Environment.NewLine); 
       ////sb.Append(string.Format("Cert.ChainStatus='{0}'", string.Join(",", chain.ChainStatus.ToList())) + System.Environment.NewLine); 

       foreach (X509ChainStatus cstat in chain.ChainStatus) 
       { 
        sb.Append(string.Format("X509ChainStatus::'{0}'-'{1}'", cstat.Status.ToString(), cstat.StatusInformation) + System.Environment.NewLine); 
       } 

       X509ChainElementCollection ces = chain.ChainElements; 
       ShowX509ChainElementCollection(sb, ces); 
       sb.Append("-X509Chain(End)-" + System.Environment.NewLine); 
      } 

      string result = sb.ToString(); 
      Console.WriteLine(result); 
     } 

     private static void ShowX509Extension(StringBuilder sb, int x509ExtensionCount, X509Extension ext) 
     { 
      sb.Append(string.Empty + System.Environment.NewLine); 
      sb.Append(string.Format("--------X509ExtensionNumber(Start):{0}", x509ExtensionCount) + System.Environment.NewLine); 
      sb.Append(string.Format("X509Extension.Critical='{0}'", ext.Critical) + System.Environment.NewLine); 

      AsnEncodedData asndata = new AsnEncodedData(ext.Oid, ext.RawData); 
      sb.Append(string.Format("Extension type: {0}", ext.Oid.FriendlyName) + System.Environment.NewLine); 
      sb.Append(string.Format("Oid value: {0}", asndata.Oid.Value) + System.Environment.NewLine); 
      sb.Append(string.Format("Raw data length: {0} {1}", asndata.RawData.Length, Environment.NewLine) + System.Environment.NewLine); 
      sb.Append(asndata.Format(true) + System.Environment.NewLine); 

      X509BasicConstraintsExtension basicEx = ext as X509BasicConstraintsExtension; 
      if (null != basicEx) 
      { 
       sb.Append("-X509BasicConstraintsExtension-" + System.Environment.NewLine); 
       sb.Append(string.Format("X509Extension.X509BasicConstraintsExtension.CertificateAuthority='{0}'", basicEx.CertificateAuthority) + System.Environment.NewLine); 
      } 

      X509EnhancedKeyUsageExtension keyEx = ext as X509EnhancedKeyUsageExtension; 
      if (null != keyEx) 
      { 
       sb.Append("-X509EnhancedKeyUsageExtension-" + System.Environment.NewLine); 
       sb.Append(string.Format("X509Extension.X509EnhancedKeyUsageExtension.EnhancedKeyUsages='{0}'", keyEx.EnhancedKeyUsages) + System.Environment.NewLine); 
       foreach (Oid oi in keyEx.EnhancedKeyUsages) 
       { 
        sb.Append(string.Format("------------EnhancedKeyUsages.Oid.FriendlyName='{0}'", oi.FriendlyName) + System.Environment.NewLine); 
        sb.Append(string.Format("------------EnhancedKeyUsages.Oid.Value='{0}'", oi.Value) + System.Environment.NewLine); 
       } 
      } 

      X509KeyUsageExtension usageEx = ext as X509KeyUsageExtension; 
      if (null != usageEx) 
      { 
       sb.Append("-X509KeyUsageExtension-" + System.Environment.NewLine); 
       sb.Append(string.Format("X509Extension.X509KeyUsageExtension.KeyUsages='{0}'", usageEx.KeyUsages) + System.Environment.NewLine); 
       sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.CrlSign='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.CrlSign) != 0) + System.Environment.NewLine); 
       sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DataEncipherment='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.DataEncipherment) != 0) + System.Environment.NewLine); 
       sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DecipherOnly='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.DecipherOnly) != 0) + System.Environment.NewLine); 
       sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.DigitalSignature='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.DigitalSignature) != 0) + System.Environment.NewLine); 
       sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.EncipherOnly='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.EncipherOnly) != 0) + System.Environment.NewLine); 
       sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyAgreement='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.KeyAgreement) != 0) + System.Environment.NewLine); 
       sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyCertSign='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.KeyCertSign) != 0) + System.Environment.NewLine); 
       sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.KeyEncipherment='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.KeyEncipherment) != 0) + System.Environment.NewLine); 
       sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.None='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.None) != 0) + System.Environment.NewLine); 
       sb.Append(string.Format("X509KeyUsageExtension.KeyUsages.X509KeyUsageFlags.NonRepudiation='{0}'", (usageEx.KeyUsages & X509KeyUsageFlags.NonRepudiation) != 0) + System.Environment.NewLine); 
      } 

      X509SubjectKeyIdentifierExtension skIdEx = ext as X509SubjectKeyIdentifierExtension; 
      if (null != skIdEx) 
      { 
       sb.Append("-X509SubjectKeyIdentifierExtension-" + System.Environment.NewLine); 
       sb.Append(string.Format("X509Extension.X509SubjectKeyIdentifierExtension.Oid='{0}'", skIdEx.Oid) + System.Environment.NewLine); 
       sb.Append(string.Format("X509Extension.X509SubjectKeyIdentifierExtension.SubjectKeyIdentifier='{0}'", skIdEx.SubjectKeyIdentifier) + System.Environment.NewLine); 
      } 

      sb.Append(string.Format("--------X509ExtensionNumber(End):{0}", x509ExtensionCount) + System.Environment.NewLine); 
     } 

     private static void ShowX509Extensions(StringBuilder sb, string cert2SubjectName, X509ExtensionCollection extColl) 
     { 
      int x509ExtensionCount = 0; 
      sb.Append(string.Format("--------ShowX509Extensions(Start):for:{0}", cert2SubjectName) + System.Environment.NewLine); 
      foreach (X509Extension ext in extColl) 
      { 
       ShowX509Extension(sb, ++x509ExtensionCount, ext); 
      } 

      sb.Append(string.Format("--------ShowX509Extensions(End):for:{0}", cert2SubjectName) + System.Environment.NewLine); 
     } 

     private static void ShowX509Certificate2(StringBuilder sb, X509Certificate2 cert2) 
     { 
      if (null != cert2) 
      { 
       sb.Append(string.Format("X509Certificate2.SubjectName.Name='{0}'", cert2.SubjectName.Name) + System.Environment.NewLine); 
       sb.Append(string.Format("X509Certificate2.Subject='{0}'", cert2.Subject) + System.Environment.NewLine); 
       sb.Append(string.Format("X509Certificate2.Thumbprint='{0}'", cert2.Thumbprint) + System.Environment.NewLine); 
       sb.Append(string.Format("X509Certificate2.HasPrivateKey='{0}'", cert2.HasPrivateKey) + System.Environment.NewLine); 
       sb.Append(string.Format("X509Certificate2.Version='{0}'", cert2.Version) + System.Environment.NewLine); 
       sb.Append(string.Format("X509Certificate2.NotBefore='{0}'", cert2.NotBefore) + System.Environment.NewLine); 
       sb.Append(string.Format("X509Certificate2.NotAfter='{0}'", cert2.NotAfter) + System.Environment.NewLine); 
       sb.Append(string.Format("X509Certificate2.PublicKey.Key.KeySize='{0}'", cert2.PublicKey.Key.KeySize) + System.Environment.NewLine); 

       ////List<X509KeyUsageExtension> keyUsageExtensions = cert2.Extensions.OfType<X509KeyUsageExtension>().ToList(); 
       ////List<X509Extension> extensions = cert2.Extensions.OfType<X509Extension>().ToList(); 

       ShowX509Extensions(sb, cert2.Subject, cert2.Extensions); 
      } 
     } 

     private static void ShowX509ChainElementCollection(StringBuilder sb, X509ChainElementCollection ces) 
     { 
      int x509ChainElementCount = 0; 
      foreach (X509ChainElement ce in ces) 
      { 
       sb.Append(string.Empty + System.Environment.NewLine); 
       sb.Append(string.Format("----X509ChainElementNumber:{0}", ++x509ChainElementCount) + System.Environment.NewLine); 
       sb.Append(string.Format("X509ChainElement.Cert.SubjectName.Name='{0}'", ce.Certificate.SubjectName.Name) + System.Environment.NewLine); 
       sb.Append(string.Format("X509ChainElement.Cert.Issuer='{0}'", ce.Certificate.Issuer) + System.Environment.NewLine); 
       sb.Append(string.Format("X509ChainElement.Cert.Thumbprint='{0}'", ce.Certificate.Thumbprint) + System.Environment.NewLine); 
       sb.Append(string.Format("X509ChainElement.Cert.HasPrivateKey='{0}'", ce.Certificate.HasPrivateKey) + System.Environment.NewLine); 

       X509Certificate2 cert2 = ce.Certificate as X509Certificate2; 
       ShowX509Certificate2(sb, cert2); 

       ShowX509Extensions(sb, cert2.Subject, ce.Certificate.Extensions); 
      } 
     } 

     private static void ShowX509Certificate(StringBuilder sb, X509Certificate cert) 
     { 
      sb.Append("-----------------------------------------------" + System.Environment.NewLine); 
      sb.Append(string.Format("Cert.Subject='{0}'", cert.Subject) + System.Environment.NewLine); 
      sb.Append(string.Format("Cert.Issuer='{0}'", cert.Issuer) + System.Environment.NewLine); 

      sb.Append(string.Format("Cert.GetPublicKey().Length='{0}'", cert.GetPublicKey().Length) + System.Environment.NewLine); 

      X509Certificate2 cert2 = cert as X509Certificate2; 
      ShowX509Certificate2(sb, cert2); 
     } 
    } 
} 
Смежные вопросы