9

Es la primera vez que tengo que utilizar la autenticación de certificados. Un socio comercial expone dos servicios, un servicio web XML y un servicio HTTP. Tengo que acceder a ambos con clientes .NET.acceder a un servicio web y una interfaz HTTP usando la autenticación de certificados

Lo que he tratado

0. Configuración del entorno

He instalado los SSLCACertificates (en la raíz y dos intermedios) y el certificado de cliente en mi máquina local (win 7 profesional) utilizando certmgr.exe.

1. Para el servicio web

  • que tienen el certificado de cliente (der).
  • El servicio será consumido a través de un proxy .NET.

Aquí está el código:

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); 

Excepción se informó en la última declaración: The request failed with an empty response.

2. Para la interfaz HTTP

  • es una interfaz HTTPS Tengo que llamar a través del método POST.
  • La solicitud HTTPS será envía desde un cliente .NET utilizando HttpWebRequest.

Aquí está el código:

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()); 

Excepción se informó en la última declaración: The request was aborted: Could not create SSL/TLS secure channel.

3. Por último intento: usando el navegador

En Chrome, después de instalar los certificados, si intento acceder a ambas URL me sale un error 107:

Error 107 (net::ERR_SSL_PROTOCOL_ERROR) 

estoy atascado.

+1

U no puede hacer peticiones HTTP con certificados SSL athorization. Es necesario hacerlo a través de https. ¿Necesitas este certificado? Si la respuesta es sí, entonces debe hacer que este servicio web se comunique a través de https. – harry180

+0

@ harry180. Gracias por aclarar Edité la pregunta. –

+0

en el protocolo http cuando se le enviará un nombre de usuario y pasword es deben estar encriptados mínima en MD5. Incluso cuando haces eso, es bastante fácil filtrar esta información a personas no autorizadas. Reconsidere el uso del protocolo https para ese tipo de intercambio de información. – harry180

Respuesta

5

El siguiente debería ayudar a identificar el problema, aquí hay dos métodos para probar la conectividad SSL se pone a prueba el sitio, mientras que el otro es un método de devolución de llamada para identificar por qué no SSL. Si nada más debería darle una mejor idea de por qué está fallando.

Cuando se llama al método que aparecerá con el cuadro de diálogo de selección de certificado, obviamente, cuando se hace esto de verdad que usted quiere leer desde el almacén cert automáticamente. El motivo por el que lo incluí es porque si no se encuentra un certificado válido, sabrá que su problema está relacionado con la forma en que se instaló el certificado.

Lo mejor que puede hacer es poner este código en un simple aplicación de consola:

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(); 
    } 
} 

/// <summary> 
/// Certificate validation callback. 
/// </summary> 
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; 
} 
+0

Muchas gracias. Lo probaré. –

Cuestiones relacionadas