Доступ к веб-службе и HTTP-интерфейсу с использованием проверки подлинности сертификатов

Это первый раз, когда я должен использовать аутентификацию сертификата. Коммерческий партнер предоставляет две службы, веб-службу XML и службу HTTP. Мне нужно получить доступ к обоим из них с .NET-клиентами.

Что я пробовал

0. Настройка среды

Я установил SSLCACertificates (на корневом и два промежуточных) и сертификат клиента на моей локальной машине (win 7 professional), используя certmgr.exe.

1. Для веб-службы

  • У меня есть клиентский сертификат (der).
  • Услуга будет использоваться через .NET-прокси.

Вот код:

OrderWSService proxy = new OrderWSService(); string CertFile = "ClientCert_DER.cer"; proxy.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate(CertFile)); orderTrackingTO ot = new orderTrackingTO() { order_id = "80", tracking_id = "82", status = stateOrderType.IN_PREPARATION }; resultResponseTO res = proxy.insertOrderTracking(ot); 

Исключение было сообщено в последнем утверждении: The request failed with an empty response .

2. Для интерфейса HTTP

  • это интерфейс HTTPS, который я должен вызвать через метод POST.
  • Запрос HTTPS будет отправлен с .NET-клиента с использованием HTTPWebRequest.

Вот код:

 string PostData = "MyPostData"; //setting the request HttpWebRequest req; req = (HttpWebRequest)HttpWebRequest.Create(url); req.UserAgent = "MyUserAgent"; req.Method = "POST"; req.ContentType = "application/x-www-form-urlencoded"; req.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate(CertFile, "MyPassword")); //setting the request content byte[] byteArray = Encoding.UTF8.GetBytes(PostData); Stream dataStream = req.GetRequestStream(); dataStream.Write(byteArray, 0, byteArray.Length); dataStream.Close(); //obtaining the response WebResponse res = req.GetResponse(); r = new StreamReader(res.GetResponseStream()); 

Исключение, указанное в последнем заявлении: The request was aborted: Could not create SSL/TLS secure channel .

3. Последняя попытка: использование браузера

В Chrome после установки сертификатов, если я пытаюсь получить доступ к обоим URL-адресам, я получаю ошибку 107:

 Error 107 (net::ERR_SSL_PROTOCOL_ERROR) 

Я застрял.

Следующее должно помочь вам определить проблему, вот два метода проверки соединения SSL: один тестирует сайт, а другой – метод обратного вызова, чтобы определить, почему SSL не удалось. Если ничто другое не должно дать вам лучшего представления о том, почему он терпит неудачу.

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

Лучше всего сделать этот код в простом консольном приложении:

 using System.Security.Cryptography.X509Certificates; using System.Net.Security; using System.Net; private static void CheckSite(string url, string method) { X509Certificate2 cert = null; ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate; X509Store store = new X509Store(StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection certcollection = (X509Certificate2Collection)store.Certificates; // pick a certificate from the store cert = X509Certificate2UI.SelectFromCollection(certcollection, "Caption", "Message", X509SelectionFlag.SingleSelection)[0]; store.Close(); HttpWebRequest ws = (HttpWebRequest)WebRequest.Create(url); ws.Credentials = CredentialCache.DefaultCredentials; ws.Method = method; if (cert != null) ws.ClientCertificates.Add(cert); using (HttpWebResponse webResponse = (HttpWebResponse)ws.GetResponse()) { using (Stream responseStream = webResponse.GetResponseStream()) { using (StreamReader responseStreamReader = new StreamReader(responseStream, true)) { string response = responseStreamReader.ReadToEnd(); Console.WriteLine(response); responseStreamReader.Close(); } responseStream.Close(); } webResponse.Close(); } } ///  /// Certificate validation callback. ///  private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) { // If the certificate is a valid, signed certificate, return true. if (error == System.Net.Security.SslPolicyErrors.None) { return true; } Console.WriteLine("X509Certificate [{0}] Policy Error: '{1}'", cert.Subject, error.ToString()); return false; }