C# HTTPS请求使用HttpClient失败
我正在使用以下代码并获取C# HTTPS请求使用HttpClient失败,c#,asp.net-core,.net-core,x509certificate,x509certificate2,C#,Asp.net Core,.net Core,X509certificate,X509certificate2,我正在使用以下代码并获取HttpRequestExceptionexception: using (var handler = new HttpClientHandler()) { handler.ClientCertificateOptions = ClientCertificateOption.Manual; handler.SslProtocols = SslProtocols.Tls12; handler.ClientCertificates.Add(new X5
HttpRequestException
exception:
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.
}
}
例外情况:
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.
}
}
WinHttpException:发生安全错误
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()异常
System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务)
System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult()
System.Net.Http.WinHttpHandler+d_u105.MoveNext()
HttpRequestException:发送请求时出错。
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()异常
System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务)
System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult()
System.Net.Http.HttpClient+d_u58.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()异常
System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务)
System.Runtime.CompilerServices.TaskWaiter.GetResult()
HomeController.cs中的MyApp.Web.Controllers.HomeController.Test()
var response=client.GetAsync(“https://someurl.com/api.php?arg1=some&arg2=test).GetAwaiter().GetResult();
lambda_方法(闭包、对象、对象[])
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+d_u27.MoveNext()
我还尝试将相同的证书导出到Windows证书库,并通过Google Chrome使用它,效果很好(浏览器要求我确认已安装的证书,然后加载资源)
为什么它在我的代码中不起作用
已更新
我还尝试添加回调以验证证书:
handler.ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) =>
{
// I set a breakpoint to this point but it is not catched.
return true;
};
更新2
该证书用于SHA-1。Neil Moss在评论中提到。
如果这是它不起作用的真正原因,有解决办法吗
解决方案
谢谢尼尔·莫斯的解决方案。他建议对SSL协议使用Tls标志
handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
但它还要求:
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
在我添加这个之后,它工作正常。根据,您必须使用ServicePointManager启用TLS1.2
System.Net.ServicePointManager.SecurityProtocol |=
SecurityProtocolType.Tls12 |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls; // comparable to modern browsers
同样值得注意的是,for ServicePointManager.SecurityProtocols属性声明如下:
.NETFramework4.6包含一个新的安全功能,可以阻止
连接的不安全密码和哈希算法
这表明可能存在某种形式的SHA1区块
编辑2020年9月16日
我将=assignment操作符更改为|=操作符,以便对仍然需要SSL的任何其他遗留站点的请求将继续工作。这是一个非常有用的文档。对于ASP.NET Core 2.0,答案如下(结果成功):
请提供错误的完整详细信息:类型、消息和堆栈跟踪。如果有内部异常,这是什么?嗨@Richard,我已经用异常消息和堆栈跟踪更新了我的问题。只是想澄清一下,您是否试图通过客户端证书通过HTTPS连接,或者您正在尝试包含一个自签名的服务器证书,并且希望将其视为有效的证书?完全脱离主题:为什么
client.GetAsync(…).GetAwaiter().GetResult()
?为什么不干脆等待client.GetAsync(…)
?您的证书是否使用SHA1签名?正在撤销对SHA1证书的支持-可能相关?非常感谢你,尼尔·莫斯!在我添加了Tls协议之后,它工作了!但据我所知,没有System.Net.ServicePointManager.SecurityProtocol
,但我使用了handler.SslProtocols=SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls代码>需要注意的重要事项是,对于.net core 2.0,您需要使用HttpClientHandler而不是ServicePointManager。当我们请求任何https网站时,ServicePointManager会做什么?感谢您提供此代码片段,它可能会提供一些有限的短期帮助。通过说明为什么这是一个很好的问题解决方案来正确解释它的长期价值,并将使它对未来有其他类似问题的读者更有用。请在您的回答中添加一些解释,包括您所做的假设。