c# asp.net-core .net-core x509certificate x509certificate2

c# - La solicitud HTTPS falla al usar HttpClient



asp.net-core .net-core (1)

De acuerdo con esta publicación SO , debe habilitar TLS1.2 con ServicePointManager.

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; // comparable to modern browsers

También cabe destacar que la documentación de MSDN para la propiedad ServicePointManager.SecurityProtocols realiza esta declaración:

.NET Framework 4.6 incluye una nueva característica de seguridad que bloquea algoritmos inseguros de cifrado y hash para las conexiones.

lo que sugiere que alguna forma de bloque SHA1 podría estar en su lugar.

Estoy usando el siguiente código y obtengo la excepción HttpRequestException :

using (var handler = new HttpClientHandler()) { handler.ClientCertificateOptions = ClientCertificateOption.Manual; handler.SslProtocols = SslProtocols.Tls12; handler.ClientCertificates.Add(new X509Certificate2(@"C:/certificates/cert.pfx")); // I also tried to add another certificates that was provided to https access // by administrators of the site, but it still doesn''t work. //handler.ClientCertificates.Add(new X509Certificate2(@"C:/certificates/cert.crt")); //handler.ClientCertificates.Add(new X509Certificate2(@"C:/certificates/cert_ca.crt")); using (var client = new HttpClient(handler)) { var response = client.GetAsync("https://someurl.com/api.php?arg1=some&arg2=test").GetAwaiter().GetResult(); // ^ HttpRequestException: An error occurred while sending the request. } }

La excepción:

WinHttpException: A security error occurred System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult() System.Net.Http.WinHttpHandler+<StartRequest>d__105.MoveNext() HttpRequestException: An error occurred while sending the request. System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult() System.Net.Http.HttpClient+<FinishSendAsync>d__58.MoveNext() System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) System.Runtime.CompilerServices.TaskAwaiter.GetResult() MyApp.Web.Controllers.HomeController.Test() in HomeController.cs var response = client.GetAsync("https://someurl.com/api.php?arg1=some&arg2=test").GetAwaiter().GetResult(); lambda_method(Closure , object , Object[] ) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeActionMethodAsync>d__27.MoveNext()

También traté de exportar los mismos certificados al Windows Certificate Store y usarlo a través de Google Chrome y funciona bien (el navegador me pidió que confirmara el certificado instalado y luego cargó el recurso).

¿Por qué no está funcionando en mi código?

ACTUALIZADO

También traté de agregar devolución de llamada para validar el certificado:

handler.ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => { // I set a breakpoint to this point but it is not catched. return true; };

ACTUALIZADO2

El certificado se usa SHA-1. Neil Moss se menciona en los comentarios que el soporte para certificaciones SHA1 está siendo retirado . Si es la verdadera razón por la que no funciona, ¿hay alguna solución para ello?

SOLUCIÓN

Gracias Neil Moss por la solución. Propuso usar la bandera Tls para el protocolo SSL.

handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;

Pero también requirió lo siguiente:

handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;

Después de que agregué este, funciona bien.