Estoy desarrollando una aplicación web ASP.NET que envía una solicitud a otro servidor usando HttpWebRequest. Envía la solicitud a través de HTTPS y el servidor remoto requiere un certificado de cliente. La solicitud falla en la aplicación .NET, aparentemente no puede enviar el certificado de cliente correcto. I am capaz de conectar con éxito y enviar el certificado del cliente si simplemente visito la URL con un navegador web (específicamente Chrome).. La aplicación .NET no puede enviar el certificado del cliente: ¿gana 7 frente a Win XP?
El siguiente código es una reproducción simple, con solo una solicitud GET básica.
var r = WebRequest.Create(url) as HttpWebRequest;
r.ClientCertificates = new X509CertificateCollection { myX509Cert };
using (var resp = r.GetResponse() as HttpWebResponse) {
...
}
que tener en nuestras excepción favorito, "No se pudo crear un canal seguro SSL/TLS". Normalmente, este tipo de problemas apuntan a problemas con los permisos en la clave privada de su certificado. Intenté todo lo que pude pensar para asegurarme de que todo esté configurado correctamente, pero tal vez me perdí algo. Para abreviar, el servidor remoto está enviando un TLS CertificateRequest
con una lista que parece identificar correctamente mi certificado de cliente, pero mi aplicación no responde con ningún certificado de cliente.
Aquí está mi configuración:
- Windows 7 Professional de 64 bits
- capaz de reproducir el problema en un 3/4 aplicación .NET ASP.NET MVC se ejecuta en el servidor dev Estudio Visual, ASP. Aplicación NET WebForms/.NET 3.5 ejecutándose en IIS local, y en una aplicación de consola .NET/.NET 4
- Se ha instalado recientemente Microsoft .NET Framework 4.5. no han examinado aún si esto podría ser un problema
Aquí es todo lo que he intentado, y lo que sé:
- Este código parecía funcionar bien cuando se ejecuta en una máquina Windows XP
- me aseguró que mi certificado de cliente se importa en el equipo local, almacén de certificados personales, con los permisos de clave privada adecuadamente configurados para mí y para todos los usuarios de IIS pertinentes
- que intentó volver a instalar el certificado en mi máquina un par de veces
- He confirmado que la aplicación .NET puede acceder al certificado X509 y
HasPrivateKey
= verdadero - Aseguré que mi certificado de cliente sea válido. En realidad, es un certificado SSL para el servidor web en el que se ejecutará esta aplicación
- Configuré
PreAuthenticate = true
en el objeto de solicitud. No hacer una diferencia - Intenté fijar
ServicePointManager.Expect100Continue = false
, no hacer una diferencia - Intenté fijar
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
, pero al parecer el servidor remoto requiere TLS de modo que no está ayudando - puse un delegado
ServicePointManager.ServerCertificateValidationCallback
para volver siempre es cierto. Pero la solicitud falla antes en el saludo de TLS, incluso antes de llamar al delegado - Cuando voy a la URL en Chrome, me pide que proporcione un certificado de cliente, presenta el certificado de cliente correcto como una opción , Elijo ese certificado y obtengo una respuesta válida. También funciona correctamente cuando construyo una solicitud en Fiddler. Así que definitivamente parece ser específicamente un problema con mi código .NET, no el certificado en sí, ni el servidor remoto, etc.
- El proveedor con el que estoy trabajando tiene el mismo servicio configurado en un servidor remoto diferente, y ese servicio requiere un certificado de cliente diferente. Así que he intentado lo mismo con los diferentes URL y cert cliente y obtuve el mismo fracaso
añadí System.Net trace y vi esto:
SecureChannel # 26717201 - Tenemos certificados proporcionados por el usuario. El servidor ha especificado 6 emisor (es). Buscando certificados que coincidan con cualquiera de los emisores.
SecureChannel # 26717201 - Se fue con 0 certificados de cliente para elegir.
...
InitializeSecurityContext (A-buffers count = 2, fuera Tampón de longitud = 0, código devuelto = CertUnknown).
me permitió completa SCHANNEL logging, y vi esta advertencia:
El servidor remoto ha solicitado la autenticación de cliente SSL, pero sin certificado de cliente adecuado se puede conocer. Se intentará una conexión anónima. Esta solicitud de conexión SSL puede tener éxito o fallar, dependiendo de la configuración de la política del servidor.
me corrieron Wireshark, y vio el servidor remoto envía una CertificateRequest
, y parece tener una entrada Distinguished Name
con los valores O CN \ \ OU de mi certificado de cliente especificados con exactitud. Después de eso, mi aplicación envía una respuesta de certificado sin certificados.
Parece que me falta algo con la configuración de este certificado para funcionar correctamente con las aplicaciones .NET en Windows 7. Mi mejor opción es que hay algo diferente en mi nueva máquina con Windows 7, en comparación con la máquina XP, que está causando que esto falle ahora. No tengo acceso a un entorno de Windows XP en este momento para confirmar esto; Lo haré en un par de días, pero me gustaría resolverlo lo antes posible.
Cualquier idea sería muy apreciada. ¡Gracias!
EDIT Como se describió anteriormente, al conectarse a la URL en Chrome, el navegador me pide un certificado de cliente, y puedo proporcionar el certificado correcto y conectarme correctamente. Sin embargo, no puedo hacerlo con éxito en Internet Explorer (9). Simplemente me aparece "Internet Explorer no puede mostrar la página web", sin otras indicaciones ni explicaciones. Me dijeron que esto puede ser relevante ya que WebRequest.Create
tiene un comportamiento similar al de IE. Estoy investigando lo que esto podría significar, pero valoraría cualquier idea al respecto.
EDIT Además, debo tener en cuenta que el servidor remoto utiliza un certificado SSL autofirmado. Originalmente pensé que ese podría ser el problema, así que agregué el certificado como una raíz de confianza en MMC para que el certificado parezca válido en mi máquina. Esto no solucionó el problema.
¿Incluye el certificado la "Autenticación de cliente (1.3.6.1.5.5.7.3.2)" Extensión de uso de clave mejorada? De lo contrario, puede ser que Chrome esté siendo malo al permitir que se seleccione. –
Resulta que el certificado del cliente no tiene esta extensión de Uso de clave mejorada. Estoy bastante seguro de que este código funcionaba correctamente en el pasado cuando apuntaba a una URL remota diferente y un certificado de cliente diferente, a pesar de que el certificado de cliente no tenía el uso de clave mejorada de autenticación de cliente. Esto me da un camino para investigar, gracias. –
En realidad, Damien, me equivoqué; todos estos certificados incluyen la extensión de uso de clave mejorada de Autenticación de cliente. –